Core Data Migration Fail

3.4k views Asked by At

My app was recently crashing on the app store because I did not migrate the data. So I was following this tutorial on Core Data Migration but it does not seem to be working:

1.I created a new model version for Core Data and set it to the current version...

2.I added the following code:

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (_persistentStoreCoordinator != nil) {
        return _persistentStoreCoordinator;
    }
    
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Planner.sqlite"];
    
    NSError *error = nil;
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    NSDictionary *options = @{
                              NSMigratePersistentStoresAutomaticallyOption : @YES,
                              NSInferMappingModelAutomaticallyOption : @YES
                              };
    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {

        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }    
    
    return _persistentStoreCoordinator;
}

However when I run update the app on my iPhone it still crashes!

The changes I made was I added an entity.

Here is the crash log:

Unresolved error Error Domain=NSCocoaErrorDomain Code=134130 "The operation couldn’t be completed. (Cocoa error 134130.)" UserInfo=0x14fb4530 {URL=file:///var/mobile/Applications/E8C39F0E-027E-4D5B-8D7B-74D592290D46/Documents/Planner.sqlite, metadata={
    NSPersistenceFrameworkVersion = 479;
    NSStoreModelVersionHashes =     {
        Audio = <f195c962 11c85401 0457370e e1b037e1 24c4e393 dc38ca34 cda3bb57 a3e26f2c>;
        Classes = <3b64e147 eb41441b 73bf051f ce094443 2017845b 2faba1c7 47848618 9fd9713b>;
        Homework = <4295bdbf 75862060 c7f1a501 3b0934cd 9811e838 bc40c5d5 05f8d383 f315d1f8>;
        Notes = <b7be1214 70a89b62 924df103 397a801a 96080505 be87b0e2 408ebf24 fdddb1a7>;
        Picture = <451cd1a2 9daac38d 69165176 0cacb6c8 94d1e93d eca34239 61a15f35 573f7e40>;
        Tests = <c10b5b25 228ebceb 6099b9af c830d203 bfca8e2b c9f46ee8 c0cd648e 9ad3e742>;
        Video = <b95e2033 b45b5aaf 298fef31 e6e25685 2b842e4e f2b3d9d1 82359c5f db9c78eb>;
    };
    NSStoreModelVersionHashesVersion = 3;
    NSStoreModelVersionIdentifiers =     (
        ""
    );
    NSStoreType = SQLite;
    NSStoreUUID = "4327E676-759B-4733-A7ED-12309BD482EE";
    "_NSAutoVacuumLevel" = 2;
}, reason=Can't find model for source store}, {
    URL = "file:///var/mobile/Applications/E8C39F0E-027E-4D5B-8D7B-74D592290D46/Documents/Planner.sqlite";
    metadata =     {
        NSPersistenceFrameworkVersion = 479;
        NSStoreModelVersionHashes =         {
            Audio = <f195c962 11c85401 0457370e e1b037e1 24c4e393 dc38ca34 cda3bb57 a3e26f2c>;
            Classes = <3b64e147 eb41441b 73bf051f ce094443 2017845b 2faba1c7 47848618 9fd9713b>;
            Homework = <4295bdbf 75862060 c7f1a501 3b0934cd 9811e838 bc40c5d5 05f8d383 f315d1f8>;
            Notes = <b7be1214 70a89b62 924df103 397a801a 96080505 be87b0e2 408ebf24 fdddb1a7>;
            Picture = <451cd1a2 9daac38d 69165176 0cacb6c8 94d1e93d eca34239 61a15f35 573f7e40>;
            Tests = <c10b5b25 228ebceb 6099b9af c830d203 bfca8e2b c9f46ee8 c0cd648e 9ad3e742>;
            Video = <b95e2033 b45b5aaf 298fef31 e6e25685 2b842e4e f2b3d9d1 82359c5f db9c78eb>;
        };
        NSStoreModelVersionHashesVersion = 3;
        NSStoreModelVersionIdentifiers =         (
            ""
        );
        NSStoreType = SQLite;
        NSStoreUUID = "4327E676-759B-4733-A7ED-12309BD482EE";
        "_NSAutoVacuumLevel" = 2;
    };
    reason = "Can't find model for source store";
}

I already set the current model version.

Any help will be appreciated.

Thank you in advance,

Abdullah Shafique

According to @Scott I have to undo all the changes to my source and only change the destination

Can someone please explain the?

3

There are 3 answers

7
Vytautas On

The error says:

"Can't find model for source store";

It looks like you also modified previous model and hashes were regenerated. And they do not match, and because of that model for source store can not be found.

8
Duncan Groenewald On

When you add a new Core Data model version XCode creates another model and you are prompted to provide a Model name for the new version. So now you should have two models in the XCode project. Once you have created the new version you then need to select it and set it to be the current version to be used by the application. You keep the old version of the model in the project.

In order for Core Data to open your existing files it needs the old version of the model (model for source store). It will then perform a migration by moving the data to the new schema (or model).

So the error above indicates that you have inadvertently made changes to the original version of the model (perhaps in addition to changes to the new version). However Core Data is unable to open the file without the correct model version so you need to restore a copy of the original core data model. If all you did was add a new entity to the new model then check whether this new entity has inadvertently been added to the old model and if so simply delete it from the old version of the model.

12
Duncan Groenewald On

Try using this code to check the model versions and output the metadata

/*! The method checks the Core Data file version is compatible with the App's model version
    and then pushes the main menu view onto the navigation stack.  If not compatible it displays a 
    message to the user.

    @param file The file URL for the Core Data Store. With UIManagedDocument you have to get the 
                actual store file URL, you can't just use the UIManagedDocument file URL.
 */
-(voidcheckCoreDataFileVersion:(NSURL*)file
{
    if ([self checkVersion:file]) {

        // file version is compatible so continue (add code to push the menu view)


    } else {

        // file version is NOT compatible

        _fileOpenErrorAlert = [[UIAlertView alloc] initWithTitle:@"Unable to open Document" message:@"Please check that you have the correct application version installed" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [_fileOpenErrorAlert show];

    }
    return;
}
/*! Checks the Core Data files models version against the apps model version to see if they
    are compatible.  This will return YES if a lightweight migration can be performed and NO if NOT.

    @param fileURL The file URL for the Core Data Store. With UIManagedDocument you have to get the
                actual store file URL, you can't just use the UIManagedDocument file URL.
    @return  Returns YES if they are compatible and NO if not.
 */
- (bool)checkVersion:(NSURL*)fileURL {

    NSManagedObjectModel *model = [self managedObjectModel];

    NSLog(@" app model entity version hashes are %@", [model entityVersionHashesByName]);

    NSError *error;
    NSDictionary *metaData = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType URL:fileURL error:&error];

    if (!metaData) {
        NSLog(@“ problem getting metaData");
        NSLog(@“  - error is %@, %@", error, error.userInfo);
        return NO;
    }

    bool result = [model isConfiguration:nil compatibleWithStoreMetadata:metaData];
    if (!result) {
       NSLog(@“ file is not compatible!");
       NSLog(@“ metadata is %@", metaData);
    }

    return result;

}