New versions of a program often add new elements to the data model, and how to handle reading files from the old version and upgrading them to the new version is vital for users of the old version. It may even be necessary at times for the new version to save files in the old version’s format.
The book doesn’t explain everything you need to do to upgrade the example application: the author tells you about the Core Data issues (how to create a new version of the model, how to create a mapping model, what new classes and methods you’ll need, etc.) and how to create new Recipe objects from RecipeIngredients, but not about updating the user interface or how to create new UnitOfMeasure objects from RecipeIngredients. Creating new UnitOfMeasure objects turns out to be a matter of copying the UnitOfMeasure routine and renaming things appropriately. If you have any issues with these, just download the examples from the book’s web site, and you can dig in and figure out what you need on your own.
Version 1 to Version 2
Version two of the recipe application adds two new fields: an author field and a date last used field. Also, the Meat and Fish categories will be eliminated and folded in to the Entrée category.
My first attempts at upgrading were missing a few steps. I needed to clean the project before it would compile the new model. The next issue was an error running the mapping model: I eventually figured out that I had mis-typed $source as $souce. It took me a few minutes to spot the problem, but that simple fix let it run, creating a new V2 file with the same name as the old one, and re-naming the V1 file with an appended tilde.
I didn’t realize at first that the book didn’t talk about updating the UI. When I got to work on that, I looked in vain for an outlet for the author editing pane in the app delegate. Looking into the nib file from the book’s web site, I discovered that it was simply a matter of connecting the Edit Authors button to the authors pane’s makeKeyAndOrderFront: action. Cool, no code & and no outlet needed! After that, it was simply a matter of adding an array controller for the Author objects, and connecting the bindings appropriately.
Version 2 to Version 3
Version three of the application adds Ingredient and UnitOfMeasure objects to the app’s data, with the Ingredients having a one-to-many releationship with the RecipeIngredients, and UnitsOfMeasure having one-to-many relationships with Ingredients and RecipeIngredients. The new data model adds a cost to each ingredient, allowing construction of shopping lists with estimated costs.
Creating links between entities for the new data model requires subclasses of NSEntityMigrationPolicy, with two methods:
- (BOOL)createDestinationInstancesForSourceInstance:(NSManagedObject *)source entityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError **)error
- (BOOL)createRelationshipsForDestinationInstance:(NSManagedObject *)dInstance entityMapping:(NSEntityMapping *)mapping manager:(NSMigrationManager *)manager error:(NSError **)error
The first, createDestinationInstancesForSourceInstance:…, creates a new ingredient (or unitOfMeasure) if needed, and links it to the destination instance. The other method, createRelationshipsForDestinationInstance:… simply returns YES
Be warned that the book doesn’t cover all the details of setting up the V2 to V3 mapping model, in particular how to set up the model to call the migration policy code you set up. Dig into the book’s mapping model file to see what needs to be done and how to do it.