모델을 자동으로 마이그레이션하기 위해 Core Data를 얻으려면 어떻게해야합니까?


96

Core Data 모델의 자동 / 경량 마이그레이션에 대한 설명서를 읽었지만 구현하는 데 문제가 있습니다.

내가 이해했듯이 응용 프로그램은 보유한 모델과 장치에 존재하는 모델이 이미 동일하지 않음을 인식해야합니다. 속성 또는 관계 및 유사한 간단한 변경 만 추가 한 경우 모델을 자동으로 업그레이드해야합니다.

모든 포인터-Xcode에서 무언가를 설정해야합니까?

답변:


138

나는 이것이 매우 간단하다는 것을 알았습니다.

내 AppDelegate에서 NSPersistentStoreCoordinator를 설정했습니다. 여기에 몇 가지 옵션을 추가하여 자동 마이그레이션을 처리하도록 지시해야합니다.

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:

[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,

[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

NSError *error;
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];

if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
    // Handle error
    NSLog(@"Problem with PersistentStoreCoordinator: %@",error);
}

그런 다음 xCode에서 약간의 트릭을 수행해야합니다.

  1. xcdatamodel 파일을 선택하십시오.
  2. 상단의 디자인 메뉴를 선택한 다음 데이터 모델을 선택한 다음 모델 버전 추가를 선택합니다.
  3. 그러면 xcdatamodel 파일이 xcdatamodel 파일과 이름이 같지만 확장자가 xcdatamodeld 인 새 디렉토리로 이동됩니다.이 디렉토리에는 이름에 2가있는 두 번째 파일이 있습니다. 새 파일을 선택한 다음 디자인-> 데이터 모델-> 현재 버전 설정 ( Xcode 4에서는이 작업을 수행합니다 )
  4. 프로젝트가 호환되지 않게하는 변경 사항을 이미 적용한 경우 원본 xcdatamodel 파일에서 이러한 변경 사항을 가져옵니다. 아직 변경하지 않았다면 2.xcdatamodel 파일 (방금 현재 버전으로 만든 파일)을 편집하십시오.
  5. 이제 이전 모델이있는 장치에이 버전을 설치하면 해당 모델이 새 모델로 자동 업그레이드됩니다.

이것은 내가 원했던 것만 큼 훌륭하고 간단 해 보이지만 모델을 변경할 때 개발 중에주의해야한다고 생각합니다. 그렇지 않으면 각 변경에 대해 새 버전을 만들어야합니다.

내가 할 일은 변경된 파일을 모두 보관하고 업데이트를 배포 할 준비가되면 중간 파일을 모두 삭제하고 가장 오래된 모델과 최신 모델로 배포하는 것입니다.


업데이트 (2011 년 7 월 15 일) :

Apple에 업데이트 된 문서가 있음을 지적 해 주신 @ rockstarberlin 에게 감사드립니다 .

Xcode 4 : 관리 개체 모델의 현재 버전 설정

업데이트 : 2013 년 8 월 19 일 더 나은 링크 :

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreDataVersioning/Articles/vmModelFormat.html


Xcode 문서 뷰어와 developer.apple.com에서 사용할 수있는 Core Data Migration and Versioning Guide를 읽는 것이 좋습니다.
Hunter

1
나는 거기에서 단순히 답을 찾지 못했습니다. 어떻게하는지 알아내는 데 시간이 걸렸습니다.
Grouchal

NSInferMappingModelAutomaticallyOption은 잘 작동하지만 속성 이름 변경과 같은 단순한 매핑에만 적용됩니다. 더 복잡한 (관계, 엔티티 제거 또는 추가)의 경우 매핑 모델을 추가해야합니다. Xcode에서 NSInferMappingModelAutomaticallyOption이 선언되지 않았다고 불평하는 경우 #import <CoreData / CoreData.h>를 앱 위임 헤더 파일에 추가합니다.
Elise van Looij

내 모델에 일부 항목을 추가했는데 악명 높은 "상점을 여는 데 사용 된 모델이 상점을 만드는 데 사용 된 모델과 호환되지 않습니다."오류가 발생했습니다. 솔루션이 문제를 해결했습니다! 대단히 감사합니다!
Karsten Silz

1
이 지침을 따른 후 "이름이 다른 두 엔티티가있는 모델을 병합 할 수 없음"오류가 발생하면 아래 Santthosh의 답변을 참조하십시오.
benvolioT 2010

14

이것은 매우 도움이되었습니다. Apple 문서는 평소와 같이 매우 불완전했습니다. 이러한 변경을 수행 한 후 처음 실행할 때 "Ca n't merge models with two different entity xxx"라는 오류가 발생 했으므로 클린 빌드를 수행하는 것이 좋습니다. 깨끗한 빌드가 문제를 해결했습니다.


깨끗한 빌드로 내 문제도 해결되었습니다.
jrainbow

6

Grouchal의 대답은 완벽합니다. 그러나 빌드를 여러 번 정리 한 후에도 여전히 "Ca n't merge models with two different entity xxx"가있는 경우 ... managedObjectModel이로드되는 방식에 문제가있을 수 있습니다. . 이것 좀보세요 ... 제가 고치는 데 도움이되었습니다 ..

핵심 데이터 마이그레이션 문제


3

또한 저처럼이 게시물을 우연히 발견 한 경우 "스토어를 여는 데 사용한 모델이 스토어를 만드는 데 사용한 모델과 호환되지 않습니다."라는 오류가 발생하고 시뮬레이터를 사용하여 디버깅하고 이전 모델이 설치된 경우 시뮬레이터 앱을 재설정하거나 시뮬레이터에서 앱을 삭제하는 것도 가능합니다.

여기에서 게시물을 읽을 때까지 이것을 시도하지 않았습니다. 그 시점에서 시뮬레이터에 앱을 설치 한 다음 모델을 변경하여 앞서 언급 한 런타임 오류가 발생했음을 깨달았습니다.


1

Santthosh의 답변에 대한 후속 조치를 취하기 위해 대신 코드 스 니펫을 여기에 게시 할 것이라고 생각했습니다. 그렇지 않으면 오류가 발생 하는 initWithContentsOfURL:대신에 managedObjectModel을 만들어야합니다 mergedModelFromBundles:.

두 개의 다른 엔티티 XXX 및 XXX와 모델을 병합 할 수 없습니다.

모델 파일의 이름이 "Model"인 경우 managedObjectModel을 만드는 방법은 다음과 같습니다.

NSString *path = [[NSBundle mainBundle] pathForResource:@"Model" ofType:@"momd"];
NSURL *momURL = [NSURL fileURLWithPath:path];
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL]; 

이 블로그 게시물에 대한 크레딧 입니다.



1

나는 수년 동안이 문제를 겪어 왔으며 이러한 모든 답변을 아무 소용이 없었습니다. 오늘 나는 마침내 내가 뭘 잘못하고 있는지 알아 냈습니다. 아주 간단한 문제지만 간과했습니다. 최신 버전의 데이터 모델을 만들 때 열을 추가하는 경우 선택 사항으로 표시해야합니다. 그렇지 않으면 새 열 값이 채워지지 않기 때문에 단순 마이그레이션이 작동하지 않습니다.

새 열에 "선택 사항"이 선택되어 있는지 확인하자마자 마이그레이션을 다시 시도했고 제대로 작동했습니다.


1

다른 문제 때문에이 게시물을 우연히 발견했지만 오류는 " 스토어를 여는 데 사용 된 모델 구성이 스토어를 만드는 데 사용 된 것과 호환되지 않습니다. " 였습니다.

여기에 내 문제와 해결책이 있습니다. 내 모델에서는 구성 을 사용했습니다 . 일부 엔티티는 한 파일에 저장되고 나머지는 두 번째 파일에 저장되었습니다. (주기적으로 다운로드해야 할 몇 가지 기본값이 있으며이를 전체로 병합하는 것은 엄청난 고통이 될 것입니다). 어쨌든 나는 새로운 엔티티를 만들었습니다. 프로그램이 잘 실행되는 것 같았지만 종료 할 때마다 위의 오류가 발생했습니다.

해결책은 내 구성을보고 현재 어떤 구성에도없는 엔티티가 있음을 깨닫고이를 하나에 추가하는 것이 었습니다. 꿈처럼 달린다.

이것은 OP의 문제를 해결하지 않습니다. 그러나 아마도 구글을 통해 여기에 착륙하는 좌절 된 사람은 내가 탔던 배에있을 것입니다. :)


0

iOS 4.0 이상

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"model" withExtension:@"momd"];
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

0

Xcode 버전 5에 대한 위의 @Grouchal의 멋진 지침에 대한 사소한 편집 :

기존 : 2. 상단의 디자인 메뉴를 선택한 다음 데이터 모델을 선택한 다음 모델 버전 추가를 선택합니다.

버전 5+ : 2. 편집기 메뉴를 선택한 다음 모델 버전 추가…를 선택하고 버전 이름을 입력하고 모델 기반 (목록에서 원래 모델 선택)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.