0

Каковы наилучшие методы обновления исходных данных?Обновление основных данных в классе модели

Первый парень, который работал над этим проектом, над которым я работаю, теперь создал все связанные с Core Data функции внутри ViewController, но я хотел объявить их внутри классов модели (подкласс NSManagedObject), чтобы разделить проблемы.

Основная функция - AFP Networking postPath, которая вызывает веб-службу и возвращает массив объектов для добавления/редактирования/удаления. То, что я сделал, было создать метод класса и сделать это AFNetwork вызов внутри него:

+ (void)updateEbooksListWithSuccessBlock:(void (^)())successBlock andFailureBlock:(void (^)())failureBlock { 
NSURL *url = urlSchema (urlWebServices, @""); 
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url]; 

NSString *postPath = [NSString stringWithFormat:@"ws-ebooks-lista.php"]; 

[httpClient postPath:postPath parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { 

    if ([operation isKindOfClass:[AFHTTPRequestOperation class]]) { 
     NSDictionary *result = [[responseObject objectFromJSONData] retain]; 
     bool success = statusDoRetornoDoWebService(result); //Function that checks if the return was successful 

     //Configura o Core Data 
     NSError *error = nil; 
     NSFetchRequest *request = [[NSFetchRequest alloc] init]; 
     NSManagedObjectContext *localManagedObjectContext = [[NSManagedObjectContext alloc] init]; 
     [localManagedObjectContext setParentContext:[(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext]]; 
     NSEntityDescription *entity = [NSEntityDescription entityForName:@"Ebooks" inManagedObjectContext:localManagedObjectContext]; 
     NSPredicate *filterPredicate; 

     [request setEntity:entity]; 

     if (success) { 
      NSArray *ebookInfos = [result objectForKey:@"saida"]; 
      Ebooks *ebook; 
      NSManagedObject *objectInsert; 

      for (NSDictionary* ebookInfo in ebookInfos) { 

       filterPredicate = [NSPredicate predicateWithFormat:@"ebooks_id == %@",[ebookInfo valueForKey:@"id_ebook"]]; 
       [request setPredicate:filterPredicate]; 
       ebook = [[localManagedObjectContext executeFetchRequest:request error:&error] lastObject]; 
       objectInsert = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:localManagedObjectContext]; 

       if (ebook) { 
        if (![[ebookInfo valueForKey:@"excluido"] isEmpty]) { 
         //Delete Ebook 
        } else { 
         //Update Ebook 
        } 
       } else { 
        //Add Ebook 
       } 

       if (![localManagedObjectContext save:&error]) { 
        //Log Error 
       } 

       [objectInsert release]; 
      } 

     } 

     [request release]; 
     [localManagedObjectContext release]; 
    } 

    [successBlock invoke]; 

} failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
    //Failure 

    [failureBlock invoke]; 
}];} 

И это прекрасно работает в то время как приложение работает, но если я его закрыть (через Xcode) и открыть его снова, изменения Арен Не спасен. Я попробовал не использовать «родительский контекст» и просто использовать контекст управляемого объекта AppDelegate (поскольку обратные вызовы AFNetworking всегда выполняются в основной очереди), но не имеют успеха: данные не сохраняются. Почему это? Я делаю что-то неправильно? Это плохая практика? Должен ли я оставить все в контроллере просмотра так, как это было?

Спасибо!

ответ

3

Я думаю, что это плохая идея иметь слишком много логики, которая в конечном счете относится к вашей модели данных в классы сущности. Эти задачи просто не принадлежат. Классы сущностей должны фокусироваться только на том, что они инкапсулируют: сами экземпляры сущности.

Чтобы проиллюстрировать: подумайте о классе, который представляет собой число (например, NSNumber). Он считает, что это не удобно распространять, чтобы дать вам, скажем, массив всех четных чисел в определенных пределах или n-й член серии Фибоначчи. Кажется несостоятельным, чтобы класс числа отвечал за сохранение себя в файл или извлечение информации из Интернета.

По этим и другим причинам я считаю, что выборка и сохранение объектов Core Data принадлежит к контроллерам, а не к классам сущностей. Помните, что одной из основных идей шаблона MVC (model-view-controller) является то, что контроллер манипулирует моделью или запрашивает ее для информации, а не то, что модель манипулирует собой.

Я предполагаю, что ваши проблемы происходят главным образом из-за того, что не отделяются различные функциональные аспекты вашего приложения в достаточной мере (модель данных, постоянство, сетевые операции, взаимодействие с пользователем).

+0

Мне понравилось ваше объяснение, но это заставило меня задуматься: что, если в моем примере мне нужно было обновить список Ebooks в другом (несвязанном) контроллере? Скажите боковое меню, которое имеет ярлык для этого списка. Повторю ли код? – dccarmo

+1

Нет, у вас должен быть класс 'EbookManager', который позаботится об этой логике. Используйте singleton для инкапсуляции этой функции. – Mundi

+0

Хорошо, я принял ваш ответ. Просто быстрое наблюдение: что, если мне нужно создать функцию для загрузки книги и сохранить в основных данных информацию о загрузке. Должно ли быть выполнено в классе ViewController или Model?Кажется разумным поставить его в модельный класс, поскольку он имеет дело прямо с сущностью. – dccarmo

1

ugh ... что бы я сделал, это сделать очень обнаженным NSManagedObject подклассы ... затем расширьте их с помощью categories, таким образом, когда вы обновляете свои классы из обновленной модели, вам не нужно пытаться объединиться во всех ваша пользовательская логика.

также пользовательская логика относится к модели, модель содержит расширение категории или класса.

поэтому возьмите это дерьмо из контроллеров просмотра и поместите его в легко поддерживаемую категорию или несколько категорий, если это оправдано.

+0

Я согласен с тобой, но не расширил ли мои классы NSManagedObject тот же результат, который у меня есть сейчас (не сохраняющиеся данные)? – dccarmo

+1

@dccarmo ваши проблемы с отсутствием персистентности - это еще одна проблема, либо ваш менеджер персистентности не записывает файл на диск, либо контекст не становится сохраненным, либо он представляет ошибку, и вы игнорируете его, я не знаю Я пытался запустить ваш код. –

Смежные вопросы