Migrating the core data schema on an iOS app is like a monster in a cave. When I walk by, the monster growls and I back off.
Well not today. Today I learned to do a simple migration in an existing core data app and I confirmed what so many others had said.
It's strangely easy to do migrations... once you know how.
Unfortunately I never found anyone that would explain it, so that's what I'm doing here.
Here are the Apple docs for running a core data migration.
Somehow I, along with some others, have found these docs both too complicated and short on information.
First off, I'll assume that you have a working Core Data app that has a "Model.xcdatamodeld" defining the schema and some data in the database.
You don't have to start from scratch, and you don't mess with the existing model. Basically you will add a new version (described below) which starts out looking just like the original model.
Now you can change this "Version 2" model however you want.
NOTE: There are some limitations on what is allowed if you want to keep the migration simple - more info here. If you have to do something complicated that requires special processing (like splitting a field) then checkout the apple docs on custom migrations.
This step is critical, and I never found anyone mention it.
When you create "Model 2" it isn't automatically set as the active version. So at this point, if you installed the app on a new device it would still use the old Model. To tell the application you actually want to use "Model 2", you need to set it as the "Current":
You're almost there, but you still need to tell the code that it's OK to run the migration.
Find your code that looks like this:
[self.coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error];
Right now you don't have any options, but this is where you tell Core Data to run the migrations automatically if needed. Change it to:
NSDictionary* options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
[self.coordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error];
Next time you run the app, it should automatically add/remove fields/entities to match your new model.