views:

781

answers:

4

Hi everybody,

I'm trying to use the migration feature in CoreData. I've followed the Apple Documentation. I have a problem in the following method:

/**
 Returns the managed object model for the application.
 If the model doesn't already exist, it is created by merging all of the models found in the application bundle.
 */
- (NSManagedObjectModel *)managedObjectModel {

    if (managedObjectModel != nil) {
        return managedObjectModel;
    }
    /* 
     * NSInvalidArgumentException', reason: '*** -[NSCFArray insertObject:atIndex:]: attempt to insert nil'
     * 2010-02-17 16:27:15.338 Patrimoine[3037:207]
     */ 
    managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];    
    return managedObjectModel;
}

It appears that there is the same problem on http://iphonedevelopment.blogspot.com/2009/09/core-data-migration-problems.html

Yet I did choose the method Apple suggests, by using the menu option "Add Model Version".

Do you have any idea?

+1  A: 

I've found that using the mergedModelFromBundel: method doesn't seem to work with migration; I switched to -initWithContentsOfURL:, and it works fine. Note that you have to init it with a URL pointing to a ".momd" file.

Ben Gottlieb
I get `Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Cannot create an NSPersistentStoreCoordinator with a nil model'` (the file url is correct).This error happens in:`persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];`
charlax
There's no *need* to switch to initWithContentsOfURL:. The issue is, per Marcus' answer, the fact that your build product still contains the old model. It'll be fixed if you simply do a make clean. Using initWithContentsOfURL: works because you're now not picking up the old model.
mmalc
+4  A: 

You need to clean your project. As soon as you "version" your model Xcode moves it into a bundle (folder) but it does not remove the old one. What happens then is that the next time you run your app there are two copies of your model in the bundle; the old one and the new one that is inside of the momd bundle.

Doing a Project -> Clean All will resolve this issue.

Marcus S. Zarra
That's perfect! Thank you!
charlax
A: 

Thanks to everyone!

These all worked, but only after I used the Clean build option.

See this other Stack Overflow topic for more info: http://stackoverflow.com/questions/2282105/using-mergedmodelfrombundles-and-versioning-coredata

The iPhone Core Data Reference has a fairly decent write up on this. The formal process from the documentation is an "Automatic Lightweight Migration".

Thanks again, --Batgar

Batgar
+1  A: 

Also, if you rename your models at any point, be sure and repeat the "set current model" step by switching to an older then back to the newer model again. My build setting would not reset itself automatically and kept setting the "current model name" to a nonexistent model, resulting in the exact same problem.

You can always verify this setting is correct in the build product's resource folder, inside the imported .momd directory, in a file called versioninfo.plist - the setting for the current model MUST match the actual name of your model.

SG