0

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?

Community
  • 1
  • 1
Abdullah Shafique
  • 6,878
  • 8
  • 35
  • 70

3 Answers3

2

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;

}
Duncan Groenewald
  • 8,496
  • 6
  • 41
  • 76
  • Do I put these lines of code in my AppDelegate – Abdullah Shafique Dec 01 '13 at 22:33
  • Well you would need to call the `checkCoreDataFileVersion:` somewhere before creating the persistentStoreCoordinator so just call it straight after you set the value for `storeURL` and pass in the `storeURL`. – Duncan Groenewald Dec 01 '13 at 23:26
  • Oops - there was an error in the last few lines where the LOG output was being written without checking the result codes - I just updated that to include an `if (!result)` line. – Duncan Groenewald Dec 01 '13 at 23:33
  • I added the lines of code and when I ran the project I got these logs: – Abdullah Shafique Dec 01 '13 at 23:39
  • `file is not compatible!` – Abdullah Shafique Dec 01 '13 at 23:39
  • `metadata is { NSPersistenceFrameworkVersion = 479; NSStoreModelVersionHashes = { Audio = ; Classes = <3b64e147 eb41441b 73bf051f ce094443 2017845b 2faba1c7 47848618 9fd9713b>; Homework = <4295bdbf 75862060 c7f1a501 3b0934cd 9811e838 bc40c5d5 05f8d383 f315d1f8>...; ` – Abdullah Shafique Dec 01 '13 at 23:40
  • OK now add the following line just below the line where the app model is set ' NSLog(@" app model entity version hashes are %@", [model entityVersionHashesByName]); ' Then you can compare the app versionHashes to the store version hashes to see exactly which entities are not the same. – Duncan Groenewald Dec 01 '13 at 23:55
  • This is the log I am getting back: – Abdullah Shafique Dec 02 '13 at 00:15
  • `Audio = ; Classes = <3b64e147 eb41441b 73bf051f ce094443 2017845b 2faba1c7 47848618 9fd9713b>; Homework = <4295bdbf 75862060 c7f1a501 3b0934cd 9811e838 bc40c5d5 05f8d383 f315d1f8>; Notes = ; Picture = <451cd1a2 9daac38d 69165176 0cacb6c8 94d1e93d eca34239 61a15f35 573f7e40>; Tests = ; Video = <774f4a4a 2ed26588 985c4659 9a3df9b7 41e596aa ada87a91 47a19bba 4a0a52b2>;` – Abdullah Shafique Dec 02 '13 at 00:16
  • OK so somehow you have changed the Video entity because the version in the store is not the same as the version in the apps model. Think hard - what did you do? – Duncan Groenewald Dec 02 '13 at 00:27
  • In my old version I added a new entity called video – Abdullah Shafique Dec 02 '13 at 00:40
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/42296/discussion-between-duncan-groenewald-and-abdullah-shafique) – Duncan Groenewald Dec 02 '13 at 00:58
1

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.

Vytautas
  • 573
  • 3
  • 8
1

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.

Duncan Groenewald
  • 8,496
  • 6
  • 41
  • 76
  • How can I restore the old model? – Abdullah Shafique Dec 01 '13 at 21:16
  • Do you have a copy of the old model ? – Duncan Groenewald Dec 01 '13 at 21:17
  • OK and I assume its easy enough for you to recreate the new model manually. Then go to XCode and delete the current model (the whole bundle, including all the versions) and select Remove Reference. Now go the project directory using file manager and move the model bundle somewhere safe! Copy the original model bundle back to the project folder and go to XCode and select Add Files to Project, select the old model file. – Duncan Groenewald Dec 01 '13 at 21:21
  • Now create a new model version, make very sure you have selected the new model version before you start making changes. XCode often appears to have selected the new model when in fact it has not so click on the new model version file more than once to make sure. – Duncan Groenewald Dec 01 '13 at 21:24
  • Thank you so much for your help but it still is crashing. – Abdullah Shafique Dec 01 '13 at 21:32
  • Still getting the same error ? Try setting the current version back to the older version to make sure the old file can still be opened correctly. – Duncan Groenewald Dec 01 '13 at 21:50
  • Yes same error and crash :( – Abdullah Shafique Dec 01 '13 at 21:53
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/42290/discussion-between-duncan-groenewald-and-abdullah-shafique) – Duncan Groenewald Dec 01 '13 at 21:53