I wanted to add an attribute to one of the objects I manage using Core Data in my iPhone app. Because it’s a simple change, I wanted to use what Apple calls Lightweight Migration–automatically migrating the data when you make a simple change like adding a field.
I had to assemble the steps from a few different places to get it to work, partially because blog posts I found were for Xcode 3, and not even all the Apple docs have been updated for Xcode 4. Here’s the full set of steps that worked for me. For example purposes, I’m assuming your app is called YourApp, and the Core Data model is called YourData.
- Don’t make changes to the data model yet!
- Run your app in the simulator to make sure it has data set up under the current version of the entity.
- Select the YourData.xcdatamodel file and choose Editor > Add Model Version… The default numbering scheme (“YourData 2”) is probably fine.
- Select the new YourData 2.xcdatamodel file, select the entity, and add the new attribute. Make sure the right pane is visible (third button above “View” on the toolbar) and the third option within that pane is selected. Either set the attribute to be optional, or set it to have a default value–you have to choose one or the other for Lightweight Migration to work.
- Regenerate your model classes by selecting the entity, choosing File > New > New File…, then NSManagedObject subclass. Note: I first created my classes under Xcode 3, and at that time it put the .h and .m files inside of the actual YourData.xcdatamodel file (which is really a directory on the filesystem). Xcode 4 didn’t seem to give me this option, but that’s fine–to me, it makes more sense to store them with the other classes anyway. If you do put your new .h and .m files in a new location, be sure to delete the old ones.
- Select the YourData.xcdatamodeld file, go to the right panel, first option, and look for Versioned Data Model > Current Version. Set this to the newer version.
- In YourAppAppDelegate.m, find the persistentStoreCoordinator method, or wherever you call addPersistentStoreWithType:… You will probably be passing it nil for options:. Instead, pass this:
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
- Update your app to use the new attribute/property in your entity. You might want to make only small changes at first, in case something goes wrong with your auto migration.
- Run your app and test it.
I wrote these steps out after I finished, so please leave a comment to let me know if I missed something and you run into other trouble.