2012-12-17 3 views
2

Core Data Model Versioning and Data Migration Programming Guide이라는 문서를 읽었습니다. 그러나 나는 아직도 많은 기술을 습득하지 못했다. 그래서 내가 만난 사례를 게시하고 싶습니다.사례 별 핵심 데이터 이전

나는 두 개의 개체 인 RuleInstance을 가지고 있습니다. Rule의 이름은 identifier입니다. Instance에는 identifier이라는 속성이 있습니다.

모든 Rule은 고유 한 식별자를 가지며 모든 인스턴스는 Rules 중 하나와 동일한 identifier입니다. 그것은 RuleInstance 사이의 많은 관계와 비슷합니다.

내 데이터 모델의 새 버전에서 RuleInstance 사이에 일대 다 관계를 만들고 싶습니다. 어떻게 마이그레이션합니까?

+0

tkanzakic에 감사드립니다. 다음 번에 내 형식을 잘 수행 할 것입니다. :) – CarmeloS

답변

5

알아 냈습니다. 소스 버전 및 대상 버전을 설정,

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: 
          [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, 
          [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, 
          nil]; 

    if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType 

configuration:nil URL:storeURL options:options error:&error]) 
{ 
    //other code handle error 
} 

이 엑스 코드와 매핑 모델을 만들기 : 영구 저장소 코디네이터를 만들 때 먼저,이 옵션을 설정합니다.

NSEntityMigrationPolicy의 하위 클래스를 만들고 이름을 MyPolicy으로 지정하고 메서드를 덮어 씁니다.

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

이 메서드를 호출 할 때 모든 managedObjects는 대상 컨텍스트에서 작성되었지만 관계는 없습니다. 이 방법에서는 dInstance가 어떤 엔터티인지 확인하고 해당 관계를 만듭니다.

Xcode를 사용하여 매핑 모델에서 InstanceToInstance이라는 매핑 정책을 사용하는 ENTITY MAPPINGS를 MyPolicy으로 설정하십시오.

이 메서드는 각 인스턴스 개체에 대해 한 번 호출됩니다. 내 질문에, 나는이 작업을 수행해야합니다

-(BOOL)createRelationshipsForDestinationInstance:(NSManagedObject *)dInstance entityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError **)error{ 
    NSError *superError = nil; 
    BOOL mappingSuccess = [super createRelationshipsForDestinationInstance:dInstance entityMapping:mapping manager:manager error:&superError]; 
    if ([dInstance.entity.name isEqualToString:@"Rule"]){ 
     Instance *instance = (Instance*)dInstance; 
     NSFetchRequest *fetch = [[NSFetchRequest alloc] initWithEntityName:@"Instance"]; 
     fetch.predicate = [NSPredicate predicateWithFormat:@"identifier == %@",instance.identifier]; 
     NSArray *result = [manager.destinationContext executeFetchRequest:fetch]; 
     Rule *rule = [result objectAtIndex:0]; 
     instance.rule = rule; 
    } 
    return YES; 
} 

그런 다음, 규칙 및 인스턴스 사이의 관계 우주선이 경우 앱 출시를 생성됩니다.

또한 NSEntityMigrationPolicy의 하위 클래스로 생성 된 관계는 xcode의 마이그레이션 정책 편집 창에서 값 표현식을 설정하지 않아도되므로 공백으로 남겨 둡니다.

+0

멋진 해결책을 가져 주셔서 감사합니다. 내 유일한 문제는 술어 내에서'instance.identifier'에 대해'NaN'을 얻는다는 것입니다. 왜 이런 일이 일어나는 지 아십니까? http://stackoverflow.com/questions/23021817/description-of-nsmanagedobject-shows-values-but-accessing-them-shows-nan – Houman

3

관계 변경에 대해 간단한 마이그레이션을 사용할 수있는 것으로 보입니다.

새 버전을 만든 후에 관계를 변경하거나 추가하기 만하면됩니다. 자세한 내용은

은 당신이해야 할 모든 대리자에 persistentStoreCoordinator 방법에 옵션을 추가 여기 LightweightMigration

본다.

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator { 

    if (persistentStoreCoordinator != nil) { 
    return persistentStoreCoordinator; 
    } 

    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"YOURDB.sqlite"]]; 

    // handle db upgrade 
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: 
    [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, 
    [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; 

    NSError *error = nil; 
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]]; 
    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) { 
    // Handle error 
    } 

    return persistentStoreCoordinator; 
} 

그런 다음 모델을 변경하고 활성화 된 것으로 선택한 다음 앱을 다시 설치하기 만하면됩니다. 그게 전부입니다.

+0

감사합니다. 그러나 실제는 이보다 훨씬 더 복잡합니다. 이것은 수동 마이그레이션을 소개하는 예제 일뿐입니다. – CarmeloS

+0

다시. 당신이 필요로하는 것은 바로 관계를 추가하는 것입니다. – shannoga

+0

예, 그렇습니다. 그냥 관계를 추가하십시오. – CarmeloS