Search code examples
iosiphonecore-datacore-data-migration

iPhone Core Data "Automatic Lightweight Migration"


I am attempting to update an app that implements a core data store. I am adding an attribute to one of the entities.

I added the following code to my delegate class:

- (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;
}

This was from the following URL: Doc

I get the following error when executing the code:

2009-12-01 20:04:22.877

Shoppee[25633:207] Error: Error

Domain=NSCocoaErrorDomain Code=134130

UserInfo=0x1624d20 "Operation could not be completed. (Cocoa error 134130.)" 2009-12-01 20:04:22.879 Shoppee[25633:207] Unresolved error Error Domain=NSCocoaErrorDomain Code=134130 UserInfo=0x1624d20 "Operation could not be completed. (Cocoa error 134130.)", { URL = file://localhost/Users/Eric/Library/Application%20Support/iPhone%20Simulator/User/Applications/A8A8FB73-9AB9-4EB7-8F83-82F5B4467AF1/Documents/MyApp.sqlite; metadata = { NSPersistenceFrameworkVersion = 241; NSStoreModelVersionHashes = { Item = <869d4b20 088e5c44 5c345006 87d245cd 67ab9bc4 14cadf45 180251e9 f741a98f>; Store = <47c250f4 895e6fd1 5033ab42 22d2d493 7819ba75 3c0acffc 2dc54515 8deeed7a>; }; NSStoreModelVersionHashesVersion = 3; NSStoreModelVersionIdentifiers = ( ); NSStoreType = SQLite; NSStoreUUID = "8DC65301-3BC5-42BE-80B8-E44577B8F8E1"; }; reason = "Can't find model for source store"; }

It looks like I somehow need to include the original data model but I am not sure how to do that. Any suggestions?


Solution

  • To recap/Full guide:

    1. Before making any change, create a new model version.

      In Xcode 4: Select your .xcdatamodel -> Editor -> Add Model Version.

      In Xcode 3: Design -> Data Model -> Add Model Version.

      You will see that a new .xcdatamodel is created in your .xcdatamodeld folder (which is also created if you have none).

    2. Save.

    3. Select your new .xcdatamodel and make the change you wish to employ in accordance with the Lightweight Migration documentation.

    4. Save.

    5. Set the current/active schema to the newly created schema.

      With the .xcdatamodeld folder selected:

      In Xcode 4: Utilities sidebar -> File Inspector -> Versioned Core Data Model -> Select the new schema.

      In Xcode 3: Design > Data Model > Set Current Version.

      The green tick on the .xcdatamodel icon will move to the new schema.

    6. Save.

    7. Implement the necessary code to perform migration at runtime.

      Where your NSPersistentStoreCoordinator is created (usually AppDelegate class), for the options parameter, replace nil with the following code:

      [NSDictionary dictionaryWithObjectsAndKeys:
                        [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, 
                        [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]
      
    8. Run your app. If there's no crash, you've probably successfully migrated :)

    9. When you have successfully migrated, the migration code (step 7) can be removed. (It is up to the developer to determine when the users of a published app can be deemed to have migrated.)

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