2011-08-11 5 views
5

설명서가 매우 제한적이며 문제점 해결 방법이 없습니다.핵심 데이터 버전 관리 및 사용자 지정 정책을 사용하여 마이그레이션

새로운 엔티티 (기존 엔티티와의 관계가 있음)를 추가해야합니다. 또한 기존 엔티티의 일부 속성을 추가하고 이름을 바꿉니다.

경량화 예 :

오래된 모델은 하나 개의 속성 name 하나의 엔티티 Item 있습니다.

새 모델에서는 Item에 새로운 속성 dateAddednametitle으로 변경하고 싶습니다. 이 시점에서 dateAdded이 선택적이거나 기본값이 주어지면 간단한 마이그레이션 기능을 사용할 수 있습니다. 내가 틀렸다면 나를 바로 잡아라.

그러나 title 속성이있는 새로운 List 엔티티를 추가하고 싶습니다. 그리고 일대일 관계를 추가하십시오. 목록은 비어 있거나 많은 항목을 가질 수 있습니다. 항목은 정확히 하나의 목록을 참조해야합니다.

그래서 나는 무엇을해야하며 어떤 순서로해야하는지 혼란 스럽습니다.

  1. 경량 마이그레이션 기능을 비활성화하여 마이 그 레이션을 사용하지 않도록 설정하십시오 (NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:NO], NSInferMappingModelAutomaticallyOption, nil];).

  2. 모델의 새 버전을 만드십시오. 나는 내가 원하는 변화를한다.

  3. 새 매핑 모델을 만듭니다. 근원은 오래된 모형, 표적은 새로운 모형이다. ItemToItem에서 title$source.name으로 설정했습니다.

매핑 모델로 작업 할 때 Xcode가 계속 충돌하는 대신 다음에 무엇을해야할지 모릅니다. 컨텍스트 내에서 List 인스턴스를 하나 만들고 관계 정책으로 인해 모든 항목을 참조해야한다고 생각합니다. 그리고 나는 이것을하기 위해 사용자 정의 NSEntityMigrationPolicy을 사용해야합니다. 이 도전을 성취하기위한 도움이 필요합니까?

답변

9

글쎄, 해냈어 ...

처음 세 단계가 정확했다. 계속 시나리오 :

ADD4. ItemToItemMigrationPolicy, 서브 클래스 NSEntityMigrationPolicy을 수행하십시오. 재정의 :

- (BOOL)beginEntityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError **)error 
{ 
    List* list = (List*)[NSEntityDescription insertNewObjectForEntityForName:@"List" inManagedObjectContext:[manager destinationContext]]; 
    list.name = @"Default list"; 

    return YES; 
} 

- (BOOL)createDestinationInstancesForSourceInstance:(NSManagedObject *)sInstance entityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError **)error 
{ 
    Item* item = (Item*)[NSEntityDescription insertNewObjectForEntityForName:[mapping destinationEntityName] inManagedObjectContext:[manager destinationContext]]; 
    item.dateAdded = [NSDate date]; 
    task.title = [sInstance valueForKey:@"name"]; 

    [manager associateSourceInstance:sInstance withDestinationInstance:item forEntityMapping:mapping]; 

    return YES; 
} 

- (BOOL)createRelationshipsForDestinationInstance:(NSManagedObject *)dInstance entityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError **)error 
{ 

    NSFetchRequest* fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"List"]; 
    NSPredicate* predicate = [NSPredicate predicateWithFormat:@"name LIKE 'Default list'"]; 
    fetchRequest.predicate = predicate; 

    NSError* fetchRequestError = nil; 
    NSArray* listsArray = [manager.destinationContext executeFetchRequest:fetchRequest error:&fetchRequestError]; 
    if (fetchRequestError) { 
     NSLog(@"%@", fetchRequestError.localizedDescription); 
    } 
    List* list = [listsArray lastObject]; 

    ((Item*)dInstance).list = list; 

    return YES; 
} 

ADD5 매핑 모델의 Xcode에서 ItemToItem 마이그레이션 정책을 사용자 지정으로 ItemToItemMigrationPolicy 값으로 설정합니다.

ADD6. 새 모델 버전을 최신 버전으로 만들고 새 항목이나 변경된 항목에서 클래스를 생성 (바꾸기)하십시오.

ADD7. 코드에서 변경을 수행하십시오 (예 : item.name). 이제는 item.title입니다. 프로젝트를 청소하고 실행하십시오.

+0

왜 중량이 가벼워 야 할 필요가 없습니까? 그것은 나를 위해 일하고있다. 그래서 내 꿈의 코드가 틀린거야? !! – khunshan

1

새 엔티티를 추가하는 경우 사용자 정의 매핑 모델을 사용하고 간단한 마이그레이션을 해제해야합니다.

중요한 한 가지. 마이그레이션 작업을 할 때마다 항상 충돌이 발생한 경우 항상 기존 영구 저장소의 새로운 예부터 시작해야합니다. 그렇지 않으면 스토어가 손상되어 눈싸움에 오류가 발생할 수 있습니다.

+0

나는 나의 이주 이니셔티브의 중간에있다. AFAIK, 당신은 마이 그 레이션을 시도하기 전에 저장소 손상 및 부작용을 방지하고 임시 저장소를 제거 할 수 있습니다. 또한 사용자 개입, 정전 등의 이유로 마이그레이션이 실패한 경우 앱이 손상된 상점으로 이전을 시도하지 않도록 보장합니다. – stephen

관련 문제