CoreData Tutorial Part 5/5 - Model Versioning, Lightweight Migration, Model Mapping
IOS 8.3 Xcode 6.3.
Before you start, here is the first and second part of this series:
Core Data tutorial Part 1 / 5 - Create Core Data Managed Object Model with Attributes, Relationships and Delete Rules
Youtube Video Part 1
Core Data tutorial Part 2 / 5 - Save Entity’s Attributes, Relationships, and make FetchRequest
Youtube video for part 2
Core Data tutorial Part 3 / 5 - Edit, Delete Objects
Youtube video for part 3
Core Data part 4 / 5 - Change Core Data model, using SortDescriptor, NSPredicate FetchRequest and filter Array using Predicate
Core Data Part 4.2. / 5 - Using NSFetchedResultsController, Reorder/Moving Table View Cells with Long Press Gesture, and update immediately Core Data displayOrder attribute
Youtube video for part 4
Check my article: “You must to know! Collection - Core Data simple explanations”
Steps in part 5 :
Add New Managed Object Model Versions
Set Lightweight Migration
Add Model Mappings
Test
When you need to change your Core Data Entities or structure, you have to add new model version before you send your App in AppStore. If you change just attributes or fetched templates, it’s not need, you can do it without consequence. But if you want to add a new Entity, you have to migrate your persistent store to a new model versions. You should also set mappings for the migration. In this tutorial we add model versions, model mappings, and using Lightweight Migration.
1. Managed Object Model Versioning
If you learn CoreData, I’m sure, you use the “delete App in Simulator before Run” method, when you change your Database and get crash when try to run your App in IOS Simulator or on your IOS device. If you work on a real App, and you want to submit it in App Store, you have to use this easy Managed Object Model Versioning method.
1.1. Add new Model
Select your CoreDataTutorial.xcdatamodeld file in your XCode, In “Editor” menu select the “Add Model Version…” submenu.
Xcode add Version name with number 2 automatically. If you use these version names in the future, you can see the changes step by step. The important thing is, the “Based on model” select Field should selected the correct actual model version.
1.2. Select the CoreDataTutorial.xcdatamodeld group, and at the right side set the new version as a current model version
1.3. Add new Entity named: “Migration”, and a new attribute: “teststring” as a String attribute.
1.4. In Editor menu **click on **“Create NSManagedObject Subclass..”. In the pop-up window select the current model versions, than thick only the “Migration” Entity. Not select the “scalar properties for primitive data types”.
2. LightWeight Migration
For Model Versioning and for Model Mapping you need to use Lightweight Migration. This will be necessary for iCloud sync too.
In Appdelegate.m file created you the NSPersistentStore. Here you need to use NSDictionary to use NSMigratePersistentStoresAutomaticallyOption and NSInferMappingModelAutomaticallyOption Both of them are YES. In this case, the first line help Core Data automatically migrate the lower versioned stores to the latest model. NSInferMappingModel help to Core Data to infer automatically the attributes of source model entities as attributes in the destination model entities.
You can add these options to your PersistentStore with this simple code: Using those two options together is called lightweight migration.
You should change your - (NSPersistentStoreCoordinator *)persistentStoreCoordinator { part of code for this with this NSDictionary line and addPersistentStore “options:nil” need to change to “options:options”:
Run the App and create some User with type and Hobby:
3. Model Mapping
When you want to say manually, which data from the earlier Model should goes which attributes to the new current model versions, you need to creata Model Mapping and change NSInferMappingModelAutomaticallyOption from YES to NO. Start with this.
**3.1. **Add a new Model Version and a new Entity
Add a new Model Version: CoreDataTutorial 3
Set the Model 3 to the current Model.
Add New Entity: MappingHome with an attribute: “hmname” as a String attribute.
Create NSManagedObjectModel Subclass…
**3.2. **Create Model Mapping
Select Data Model group, right click, New File and select Mapping Model:
Set CoreDataTutorial 2 as** Source Data** and** CoreDataTutorial 3** Model version as Target Data Model:
Save with the name: “Model2to3”:
Now you have a Mapping Model:
3.3. Set Source and Destination Data:
Click on Type Entity, and check the right side at the Entity Mapping the Source and Destination Entity names. These are the same. At the typeName attribute there is a Value Expression: “$source.typeName”, that means, the Destination typeName attribute use the typeName attribute from the source Model’s Type Entity.
Now click on your new Entity. You can see, that MappingHobby hasn’t got Value Expression, that means, no source Data.
But we would like to see here, the old Hobby Entity’s hobbyName attribute data.
Select MappingHobby Entity, at right side select “Hobby” as a Source. Now Your Entity Name chnaged from “MappingHobby” to “HoobyToMappingHobby”.
Now Add source Value Expression to the “hmname” attribute: “$source.hobbyName”.
4. Test Model Maping
Yes, we should test it. Go to
** ViewController.m**
, import
“MappingHobby.h”
file.
in ViewDidLoad create a FetchRequest for the MappingHobby Entity, and List in NSLog all of the string attribute “hmname” strings, which should be the name of the Hobby Entity. So we call them too:
Run Project —> Clean, than Run the App, and check the log, you should see the Fetched MappingHobby Object names as same as Hobby Object names.
Now you are ready to use Model Versioning with Lightweight Migration or create Model Mapping.
NEXT
Download the Xcode template from Github
The next part of the series: soon. (Export - import data, migration.)
If you would like to be notified of my new solutions, please
Subscribe to my youtube channel!
Follow me on twitter!
Like on Facebook!













