0

내 핵심 데이터를 업데이트하는 가장 좋은 방법은 무엇입니까?내 모델 클래스의 핵심 데이터 업데이트

내가이 프로젝트에서 일한 첫 번째 사람은 지금 당장 ViewController 내부의 모든 핵심 데이터 관련 함수를 만들었지 만 모델 클래스 (NSManagedObject 하위 클래스) 안에 관심사를 구분하기 위해 선언하려고했습니다.

주요 기능은 웹 서비스를 호출하고 추가/편집/삭제할 객체 배열을 반환하는 AFNetworking 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를 통해)를 닫고 다시 열 경우, 변경은 때로 믿을 수 구원받지 못했습니다. 나는 "부모 컨텍스트"방법을 사용하지 않고 단지 (AFNetworking 콜백이 항상 메인 큐에서 실행되기 때문에) AppDelegate 관리 객체 컨텍스트를 사용했지만 아무런 성공도 시도하지 못했습니다. 데이터가 지속되지 않습니다. 왜 그런가요? 내가 뭔가 잘못하고 있는거야? 나쁜 습관입니까? View Controller의 모든 것을 그대로 두어야합니까?

감사합니다.

답변

3

궁극적으로 엔티티 클래스에 데이터 모델과 관련이있는 너무 많은 논리를 갖는 것이 바람직하지 않다고 생각합니다. 이러한 작업은 단순히 여기에 속하지 않습니다. 엔티티 클래스는 캡슐화 된 것, 즉 엔티티 인스턴스 자체에만 집중해야합니다.

설명 : 숫자를 나타내는 클래스 (예 : NSNumber)를 생각해보십시오. 특정 범위 내에서 모든 짝수의 배열 또는 피보나치 시리즈의 n 번째 멤버를 제공하기 위해이를 확장하는 것이 편리하지 않다고 생각합니다. 숫자 클래스가 파일 자체를 저장하거나 웹에서 정보를 검색하는 것은 책임이 없습니다.

이와 비슷한 이유로 인해 코어 데이터 엔티티를 가져오고 저장하는 것이 엔티티 클래스가 아닌 컨트롤러에 속한다고 생각합니다. MVC (Model-View-Controller) 패턴의 기본 아이디어 중 하나는 컨트롤러가 모델을 조작하거나 정보를 요청한다는 점입니다. 모델이 자체 조작하지는 않습니다.

귀하의 문제는 주로 응용 프로그램의 다양한 기능적 측면 (데이터 모델, 지속성, 네트워크 작업, 사용자 상호 작용)을 분리하지 않아서 발생한다고 추측됩니다.

+0

나는 당신의 설명이 마음에 들었지만, 내 생각에, 다른 (관련없는) 컨트롤러에서 전자 책 목록을 업데이트해야한다면 어떻게 될까? 이 목록에 대한 바로 가기가있는 사이드 메뉴를 말하십시오. 코드를 되풀이해도 될까요? – dccarmo

+1

아니요,이 논리를 처리하는 클래스 'EbookManager'가 있어야합니다. 싱글 톤을 사용하여이 기능을 캡슐화하십시오. – Mundi

+0

괜찮아, 네 대답을 받아 들였어. 빠른 후속 조치 : 전자 북을 다운로드하고 다운로드 데이터를 핵심 데이터로 저장하는 기능을 작성해야하는 경우 어떻게해야합니까? ViewController 또는 Model 클래스에서이를 수행해야합니까?엔터티를 곧바로 다루기 때문에 모델 클래스에 두는 것이 합리적입니다. – dccarmo

1

우 ... 내가 무엇을 할 것인가는 매우 알몸이된다. NSManagedObject 하위 클래스 ... categories으로 확장하면, 업데이트 된 모델에서 클래스를 다시 생성 할 때 모든 것을 병합 할 필요가 없다. 귀하의 사용자 정의 논리.

또한 사용자 지정 논리가 모델에 속하므로 모델에 범주 또는 클래스 확장이 포함됩니다.

그래서보기 컨트롤러에서 그 쓰레기를 꺼내 쉽게 유지 관리 할 수있는 범주 또는 보증되는 경우 여러 범주에 넣으십시오.

+0

나는 당신과 동의하지만 내 NSManagedObject 클래스를 확장하지 않을 것이다. 지금 당장 가지고있는 것과 동일한 결과를 얻는다. – dccarmo

+1

@dccarmo 지속성 부족 문제가 지속성 관리자가 파일을 디스크에 쓰지 않고 있거나 컨텍스트가 저장되지 않거나 오류가 발생하여 무시하는 경우 다른 문제가 있습니다. 귀하의 코드를 실행하려고 시도하지 않았습니다. –

관련 문제