views:

62

answers:

1

I know this is a frequently asked question, however none of the solutions that I have found seem to work for me.

This is my situation: I have one data model for my application, and I wanted to add versioning to it. So in XCode, I did Design -> Data Model -> Add Model Version. I also updated my delegate's persistentStoreCoordinator method to look like this:

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    if (persistentStoreCoordinator != nil) {
        return persistentStoreCoordinator;
    }
    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory]
                                               stringByAppendingPathComponent: @"foo.sqlite"]];

    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]) {
        /*Error for store creation should be handled in here*/
    }

    return persistentStoreCoordinator;
}

Just to make sure everything was still working, I did a clean all, build, and tested it in the simulator. Everything worked so far.

Next I chose the new version data model, set it to be the current version using XCode, and added one extra attribute to an entity. I then did a clean all, build. And now whenever I start the application it crashes with this error: 'Can't merge models with two different entities named 'foo''.

What am I doing wrong? I have tried making sure that no data model is added to the target, adding just the current version data model to the target, and both. Every time I test I make sure to clean all.

Can anyone shed some light as to why it does not work for me?

EDIT:

here is my managedObjectModel method:

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

  return managedObjectModel;
}
A: 

I already expected this implementation of the managedObjectModel getter.

In your implementation all models within the bundle are merged into one single model. Therefore also all versions within the .momd are merged resulting in duplicate entity definitions.

Change the code to explicitly initialize the model with the apropriate model file and it should work fine.

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"datamodel" ofType:@"momd"];
NSURL *modelURL = [NSURL fileURLWithPath:modelPath];
managedObjectModel_ = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];    
Martin Brugger
Doing this, I get a different error: "This NSPersistentStoreCoordinator has no persistent stores. It cannot perform a save operation."
nan
Log modelPath to see if you really loaded a valid managed object model.
Martin Brugger
I ended up not using the option for inferring the mapping model automatically, and defined my own. Now everything works as expected. Thanks. I logged the error for the NSPersistentStoreCoordinator, and it says a mapping model could not be inferred.
nan