Colin Humber
Colin Humber

Reputation: 1395

iPhone CoreData migration fails with "Can't find model for source store"

I have an iPhone app that is using CoreData. I recently made some minor changes to the data model and now every time the app is opened I get an error "Can't find model for source store".

I have 2 version of the data model and the only changes I've made were some additions of some fields. I was following the guide here which worked initially, then just today, after adding some additional fields, it breaks. All additional fields are marked as optional and all have default values. The migration code is below:

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

// migration options
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                         [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                         [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

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

if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
...
}

The managedObjectModel is successfully created here:

- (NSManagedObjectModel *)managedObjectModel {

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

NSString *path = [[NSBundle mainBundle] pathForResource:@"DataModelName" ofType:@"momd"];
NSURL *momURL = [NSURL fileURLWithPath:path];
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];

return managedObjectModel;
}

I've tracked down the issue to a mismatch in the version has for 1 entity. The error that gets thrown includes this has for the entity:

MyEntityName = <cc1456b7 b12d0d05 21930308 94ccc078 27a6c345 8847c738 e3a9ae7e 0be9535d>;

but the hash in the VersionInfo.plist in the app bundle is:

MyEntityName = <fede6b59 462442d1 8fc98226 b9f8f745 3250dabd ee188248 cb97b1d0 8a74eef3>;

There are no other entities anywhere in the VersionInfo.plist with the hash <cc1456b7....>.

Upvotes: 7

Views: 3848

Answers (2)

Pankaj Wadhwa
Pankaj Wadhwa

Reputation: 3063

Well in my case exactly the same thing was happening and i was on iOS 7 and this problem screwed my head for at least a week and then finally find the solution which works for me . In order to make it work you have to add an extra value in options which is used to add PersistentStore and then you go( I am not sure about other iOS version but yeah it will definitely work on iOS 7).

-(NSManagedObjectModel *)managedObjectModel
{
    if (managedObjectModel != nil)
    {
        return managedObjectModel;
    }
    managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
    return managedObjectModel;
}

-(NSPersistentStoreCoordinator *)persistentStoreCoordinator
 {

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

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"ABC.sqlite"];

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

//Creating Lightweight migration.
    NSDictionary *options =
    @{
      NSMigratePersistentStoresAutomaticallyOption:@YES
      ,NSInferMappingModelAutomaticallyOption:@YES
      ,NSSQLitePragmasOption: @{@"journal_mode": @"DELETE"}
     };


   if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error])
    {
       NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
       abort();
    }
return persistentStoreCoordinator;
}

Upvotes: 0

tc.
tc.

Reputation: 33602

From the linked answer,

This seems great and as simple as I wanted - but I think you need to be careful during development as you change a model - otherwise you will have to create a new version for each change.

It sounds like you made version 2, edited version 2, ran the app, edited version 2 again, and ran the app again. This doesn't work so well; you need to save all the model versions you expect to be able to open. This is a bit of a hassle.

What you could do is name all your models after app versions, e.g. FooModel-1 and FooModel-1.1 corresponding to releases, and FooModel-1.2d1, FooModel-1.2d2 for "development" versions. Before release, you can rename FooModel-1.2d10 to FooModel-1.2 and remove the other development versions.

(Or I could be entirely misreading the question; sorry.)

Upvotes: 5

Related Questions