iPhone Core Data "Automatic Lightweight Migration"
Asked Answered
C

9

64

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?

Cleopatra answered 2/12, 2009 at 1:13 Comment(0)
L
145

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.

Linton answered 2/12, 2011 at 23:0 Comment(7)
Is step 9 really needed? And if so, why?Stepparent
I tried to delete old model schemas file then run the app, it seems work well. I don't know why.(xcode4.6)Smoky
Thank u and +1! Don't forget the renaming ID when renaming attributes or entities...Romanticize
thank you! +1! i have a minor problem: i have a document based application, and my document IS the database. i am stuck at point 7 as i dont know where, how and what code to implement. thanks!Cardiganshire
+1 for step 3! I got this error when I was renaming an entity and a relation. The documentation linked in step 3 helped me to rename in the right manner and fix this problem.Olwena
How to delete the newly created one? Like i have created the version 2 but it is not correct one. So i want to delete it and again make that version?Mattie
One issue I ran into: After step 1, the model file is moved into a directory, which Xcode handles for you. However, the compiled model will also have a different file extension from now, which is momd instead of mom. You may need to adapt your [[NSBundle mainBundle] URLForResource:@"ModelName" withExtension:@"mom"] code accordingly. It could be that this is only an issue with legacy code and apps generated from newer templates use the directory structure from the get go.Cockle
C
26

I figured it out.

Design > Data Model > Add Model Version

Cleopatra answered 2/12, 2009 at 1:35 Comment(3)
I have the exact same problem. I've tried a lot of different things but it still get the same reason = "Can't find model for source store" error. When you and the other posters say you need to add the original store, what do you guys mean? i posted: #2926418Castigate
Note that in Xcode 4, this menu option is gone... is it automagical?Pantalets
@Pantalets - No. For Xcode 4, select your xcdatamodeld in the project tree and then select Editor -> Add Model Version... from the menu barSalina
I
16

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.

Indwell answered 27/6, 2010 at 20:34 Comment(1)
While trying to rename an attribute I came across this post that outlines the entire process step by step. Hopefully it will help others who aren't clear on the entire process. mobile.tutsplus.com/tutorials/iphone/…Aleida
K
11

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.

Kosher answered 18/1, 2010 at 16:13 Comment(0)
C
5

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.

Choate answered 8/12, 2009 at 3:17 Comment(2)
can you elaborate on this some more? What do you mean "create a version of your original store, and a new one"? Do I just make a StationStore 3.xcdatamodel?Castigate
yes, and then use Design -> Data Model -> Set Current version while you have that new version highlightedChoate
C
1

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";

Cachou answered 1/8, 2012 at 7:53 Comment(0)
A
1

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
Anastigmatic answered 3/2, 2013 at 11:16 Comment(0)
H
0

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.

Headgear answered 21/3, 2013 at 20:45 Comment(0)
D
-1

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...

Doormat answered 18/6, 2012 at 23:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.