10

I am working on a application in which we are using x.x.xcdatamodel. Now in same x.x.xcdatamodel I have added an attribute in one of the entity. The application crashes showing the message "This NSPersistentStoreCoordinator has no persistent stores (schema mismatch or migration failure). It cannot perform a save operation.". I tried many things and i am also using lightweight migration to handle the situation but that is not working as well.Below is my code:

    - (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (__persistentStoreCoordinator != nil)
    {
        return __persistentStoreCoordinator;
    }

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

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

    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]);
    }

    return __persistentStoreCoordinator;
}




- (BOOL) saveContext
{
    @synchronized (_localStorage) {
        //NSLog(@"----------------------------Save context called---------------------------");
        BOOL result = TRUE;
        NSError *error = nil;
        NSManagedObjectContext *managedObjectContext = self.managedObjectContext;

        if (managedObjectContext != nil)
        {
            //Crashes here at this line.
            if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error])
            {
                NSLog(@"----------------------------Save context failed---------------------------");
                result = FALSE;
                NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
            }
        }

        //NSLog(@"----------------------------Save context completed---------------------------");

        return result;
    }
}

Am i missing something over here? OR Is it like i have to perform complete migration even if i add a single attribute in an entity?Thanks in advance.

Uzair Dhada
  • 333
  • 2
  • 6
  • 23

5 Answers5

19

You don't have to do the migration yourself here. You do have to add a new version of the data model. You can't edit the xcdatamodel and expect Core Data to just use the new version. You need to keep your existing model, create a new version, and make your changes in the new version. You must always have a version of the model that matches the persistent store file.

You create a new version by selecting the xcdatamodel model file in Xcode's file browser, going to the "Editor" menu, and selecting "Add Model Version..."

Tom Harrington
  • 69,312
  • 10
  • 146
  • 170
  • So whenever i want to add a new attribute to the entity and want to upload the update into the store, ill have to make a new data model? even just for one single small change? – Uzair Dhada Mar 22 '16 at 06:19
  • Yes, every time you change the data model. Usually data models don't have frequent changes, if they're planned carefully. – Tom Harrington Mar 22 '16 at 16:00
  • Ok thank you for your help, hopefully by adding new version this issue will be solved, Problem is that we are unable to reproduce it at my end but the app is crashing for the users, so its a bit difficult for me to be sure. – Uzair Dhada Mar 23 '16 at 06:21
  • @uzairdhada I know that this is an old question, but hopefully this will help. You always need to do upgrade testing when you release a new version of an app that uses CoreData. Testing upgrading from the old version to the new version of the app would have reproduced this crash for you. – siburb Oct 15 '16 at 00:44
  • 2
    I accidentally added attribute in old version of code data instead of new version. I removed those attribute from old model but now have same error. – Avijit Nagare Apr 06 '17 at 07:43
  • @AvijitNagare this is one of the reasons version control software like git exists. So that you can easily undo a change like that. – Tom Harrington Apr 07 '17 at 23:30
  • So If I accidentally changed model without creating new model version and already uploaded build to appstore and received bad feedback - what should I do? It seems - I should create new model version, that will be correct for old users and new users as well. Am I right? – Anton Belousov Jan 05 '18 at 19:39
  • If you can, yes. If you're using git or other version control software, it will help with this. – Tom Harrington Jan 05 '18 at 20:05
  • After creating a new model version, I needed to delete the app from simulator. Thought it would be the same if a device is used for testing. Thanks Tom for the answer! – wei Jul 02 '23 at 03:03
2

I work on a project and faced a similar problem, it seems that the former developer forgot to pass these two options for a lightweight migration. I passed in the second one and the migration completed successfully.

You request automatic lightweight migration using the options dictionary you pass in addPersistentStoreWithType:configuration:URL:options:error:, by setting values corresponding to both the NSMigratePersistentStoresAutomaticallyOption and the NSInferMappingModelAutomaticallyOption keys to YES:

NSError *error = nil;
NSURL *storeURL = [[NSBundle mainBundle] URLForResource:@"Model" withExtension:@"momd"];
NSPersistentStoreCoordinator *psc = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:managedObjectModel]
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

BOOL success = [psc addPersistentStoreWithType:NSSQLiteStoreType
                configuration:nil URL:storeURL
                options:options error:&error];
if (!success) {
  // Handle the error.
}
Ali Baqbani
  • 153
  • 1
  • 2
  • 13
0

In my case, I had changed the name of the xcdatamodel inside the xcdatamodeld package. I needed to revert the name change in order to remove the error.

Pranav Kasetti
  • 8,770
  • 2
  • 50
  • 71
0

I just:

  1. Delete the app from the simulator.
  2. Clean.
  3. Save the result.
  4. Build the app again.

This works perfectly for me. I do this all the time when I make changes to the original model.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
-1

tried changed the data model name from "xxx.xcdatamodeld" to from "xxx2.xcdatamodeld". It worked.