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.

NOTE

To continue building the sample application, you need to have added the previous chapter’s code to Groceries. Alternatively, you may download, unzip, and use the project up to this point from http://www.timroadley.com/LCDwS/Groceries-AfterChapter02.zip. Any time you start using an Xcode project from a ZIP file, it’s good practice to hold down option and click Product > Clean Build Folder. This practice ensures there’s no residual cache from previous projects using the same name. It is recommended that you use the iOS Simulator when following this chapter so you can inspect the contents of the SQLite database files easily.

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.

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.