- Anyone who has never made a mistake has never tried anything new.
- Albert Einstein
In Chapter 2, “Managed Object Model Basics,” the fundamentals of managed object models were introduced, yet you were constrained to just one entity and a few attributes. The next logical step is to add to the model; however, this requires a number of preliminary steps to prevent errors caused by these changes. This chapter shows how to add model versions and model mappings, and it demonstrates different migration techniques you can choose when upgrading a model.
Changing a Managed Object Model
As an application evolves, its managed object model probably needs to change, too. Simple changes, such as attribute defaults, validation rules, and fetch request templates can be modified without consequence. Other more structural changes require that persistent stores be migrated to new model versions. If a persistent store doesn’t have the appropriate mappings and settings required to migrate data from one version to the next, the application throws a “store is incompatible” error.
Update Groceries as follows to generate a “store is incompatible” error:
- Run Groceries once to ensure the existing model has been used to create the persistent store. You should see the file system location of the store printed to the console log.
- Select Model.xcdatamodeld in Xcode.
- Add a new entity and rename it to Measurement.
- Select the Measurement entity and add an attribute called abc. Set its type to String.
- Rerun the application and examine the console log. You should now have generated arguably one of the most common Core Data errors, as shown in Figure 3.1. If this error has not appeared, delete the application and then click Product > Clean and retry from step 1.
Figure 3.1 Store incompatibility
This error isn’t an issue when an application is in its initial development phase. To get past it, you can just delete the application from the device and run it again from Xcode. When the application is run for the first time after being deleted, the persistent store is created based on the latest model. This makes the store compatible with the model, so the application won’t throw the error anymore. However, it won’t have any old data in it. As such, this scenario is unacceptable for any application already available on the App Store. There are a few approaches to migrating existing persistent stores, and the migration path you choose is driven by the complexity of the changes and whether you’re using iCloud. Whatever you do, you first need to become familiar with model versioning.
Update Groceries as follows to revert to the original model:
- Select Model.xcdatamodeld.
- Delete the Measurement entity.
- Rerun the application, which now should not throw an error.