code

iPhone 핵심 데이터 "자동 경량 마이그레이션"

codestyles 2020. 11. 19. 08:15
반응형

iPhone 핵심 데이터 "자동 경량 마이그레이션"


핵심 데이터 저장소를 구현하는 앱을 업데이트하려고합니다. 엔티티 중 하나에 속성을 추가하고 있습니다.

내 대리자 클래스에 다음 코드를 추가했습니다.

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

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

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

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

    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]) {
        NSLog(@"Error: %@",error);
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }    

    return persistentStoreCoordinator;
}

다음 URL에서 가져온 것입니다. Doc

코드를 실행할 때 다음 오류가 발생합니다.

2009-12-01 20 : 04 : 22.877

Shoppee [25633 : 207] 오류 : 오류

도메인 = NSCocoaErrorDomain 코드 = 134130

UserInfo = 0x1624d20 "작업을 완료 할 수 없습니다. (Cocoa 오류 134130.)"2009-12-01 20 : 04 : 22.879 Shoppee [25633 : 207] 해결되지 않은 오류 오류 도메인 = NSCocoaErrorDomain 코드 = 134130 UserInfo = 0x1624d20 "작업을 수행 할 수 없습니다. 완료되었습니다. (Cocoa 오류 134130.) ", {URL = file : // localhost / Users / Eric / Library / Application % 20Support / iPhone % 20Simulator / User / Applications / A8A8FB73-9AB9-4EB7-8F83-82F5B4467AF1 / Documents / MyApp .sqlite; 메타 데이터 = {NSPersistenceFrameworkVersion = 241; NSStoreModelVersionHashes = {항목 = <869d4b20 088e5c44 5c345006 87d245cd 67ab9bc4 14cadf45 180251e9 f741a98f>; 스토어 = <47c250f4 895e6fd1 5033ab42 22d2d493 7819ba75 3c0acffc 2dc54515 8deeed7a>; }; NSStoreModelVersionHashesVersion = 3; NSStoreModelVersionIdentifiers = (); NSStoreType = SQLite; NSStoreUUID = "

어떻게 든 원본 데이터 모델을 포함해야하는 것 같지만 어떻게해야할지 모르겠습니다. 어떤 제안?


요약 / 전체 가이드 :

  1. 변경하기 전에 새 모델 버전을 만드십시오.

    Xcode 4에서 .xcdatamodel-> 편집기-> 모델 버전 추가를 선택하십시오 .

    Xcode 3 : 디자인-> 데이터 모델-> 모델 버전 추가.

    폴더 .xcdatamodel가 생성 된 것을 볼 .xcdatamodeld수 있습니다 (아무것도없는 경우 생성됨) .

  2. 저장.

  3. 새 항목을 선택 하고 Lightweight Migration 설명서.xcdatamodel 에 따라 채택하려는 변경을 수행 하십시오 .

  4. 저장.

  5. 현재 / 활성 스키마를 새로 생성 된 스키마로 설정합니다.

    으로 .xcdatamodeld선택한 폴더 :

    Xcode 4 : 유틸리티 사이드 바-> 파일 검사기-> 버전 화 된 코어 데이터 모델-> 새 스키마 선택.

    Xcode 3 : 디자인> 데이터 모델> 현재 버전 설정.

    .xcdatamodel아이콘 의 녹색 체크 표시 가 새 스키마로 이동합니다.

  6. 저장.

  7. 런타임에 마이그레이션을 수행하는 데 필요한 코드를 구현하십시오.

    당신은 어디에서 NSPersistentStoreCoordinator(일반적으로 AppDelegate에 클래스) 작성됩니다에 대한 options매개 변수 대체 nil다음 코드로 :

    [NSDictionary dictionaryWithObjectsAndKeys:
                      [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, 
                      [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]
    
  8. 앱을 실행하십시오. 충돌이 없다면 성공적으로 마이그레이션 한 것입니다. :)

  9. 마이그레이션이 완료되면 마이그레이션 코드 (7 단계)를 제거 할 수 있습니다. (게시 된 앱의 사용자가 마이그레이션 된 것으로 간주 될 수있는시기를 결정하는 것은 개발자의 몫입니다.)

IMPORTANT: Do not delete old model versions/schemas. Core Data needs the old version to migrate to the new version.


I figured it out.

Design > Data Model > Add Model Version


For Googlers again, this is what you need to do (assuming you have already set up Lightweight Migration):

  1. Before making changes, Do Design -> Data Model -> Add Model Version (you will see that a new .xcdatamodel is created in your .xcdatamodeld folder)
  2. Save
  3. Make your change
  4. Save
  5. Run App

Step #1 is crucial for making this work. I ran into this problem because I had followed these steps to add a new field. That worked. I added a second new field, but forgot to "Add Model Version", and things blew up.


Also for googlers.. Simple rule, never delete/edit any old numbered version. When you Add Model Version the number suffix will increase as 2..3..4 meaning 2 is the oldest 3 next etc.. but the Current one to edit is the unnumbered version.

Do not delete old model versions as users with previous db using an old model version will not be able to migrate to your latest db model with out comparing old and latest schemas.


Just a note for those that come across this Googling, it seems even with auto(magic) migration you still need to create a version of your original store, and a new one, and set the new one as the current version.


So far I only see how to avoid the error message.

But how do we fix it - in case we messed things up already??

The following solution fixed the problem but you will loose the data in the DB:

Delete / rename the sqlite file of the deployed / installed application.
The files name an location are given directly after the error message. e.g.:

reason=Can't find model for source store}, {
URL = "file://localhost/Users/yourName/Library/Application%20Support/iPhone%20Simulator/4.3/Applications/62F342D4-F007-4F6F-96D2-68F902D3719A/Documents/Locations.sqlite";


Something to keep in mind when doing a lightweight migration -

If you plan to rename/modify attributes, remember to set the "Renaming ID" value in either the new or the old model. To use Apple's own example, in XCode 4.3, select paintColor in the new model > switch to the Data Model Inspector > Set the "Renaming ID" field to Color in the "Versioning" section. For me, failure to do this step led to a run time error. This same error is also covered here. As a new user, I'm not allowed to post images, so here's an imgur link (not spam, really).

    (Cocoa error 134140.)" UserInfo=0x622b350 {reason=Can't find or automatically infer mapping model for migration

You can also get this error when making a change to the data model and running on an installed app that has a different version of the sqlite file. In this case just delete the installed app and re-run it.


Just in case someone runs into this scenario and none of the above works... I was deleting my app from the simulator, cleaning, etc, but nothing would work. I had to go to the simulator directory and manually rm the .sqlite file to get the app working again. No clue...

참고URL : https://stackoverflow.com/questions/1830079/iphone-core-data-automatic-lightweight-migration

반응형