Core data versioning and migration - iphone

I have the older version of the core data model of the released app. Now, in the next version of the app, I am migrating the core data model to new model. Is there a way to get the attribute values from the old model before actually migrating to the new version of the model or is there possibly a way to know if the migration is to be occurred.

When you migrate, Core Data actually moves existing values for you. If you're doing a relatively simple migration, such as adding or removing some properties, Core Data does its best to make the move as seamless as possible. In many cases, you won't need to make any changes other than set your new model. See my answer here for more.

Yes, it is possible.
To get the attribute values from the old model you'll need to create custom entity migration policies (NSEntityMigrationPolicy subclasses). Then in -createDestinationInstancesForSourceInstance:entityMapping:manager:error: you'll receive source instance, and it is completely up to you how to create destination instances from source instances.
There is a method to check if a given store is compatible with store coordinator model: -[NSManagedObjectModel isConfiguration:compatibleWithStoreMetadata:].

Related

Core Data Migration: Do I Need a new Mapping Model for each new Model Version I Add?

I've done a custom Core Data migration several versions back when doing some structure changes in my app. (So created a new model version, and a mapping model with custom policy class).
Now, I want to do some more changes. So I've created another model version. Now, I'm not sure whether I need to create another mapping model for this change? If I do, will core data just figure out the appropriate one to use based on the users version?
Will I also need to create another custom policy class, or can I somehow add the new logic to the first one?
Lastly, will I need to add any logic for migrating from the original database straight to the current database? Or will core data figure that out for me, and migrate to the median version first, and then to the current version when a user loads an app version with the original data structure?
Thanks!
I guess the answer to whether or not you need to create another mapping model is... it depends. See Apple's docs here (specifically comments on lightweight migration): https://developer.apple.com/library/ios/documentation/cocoa/Conceptual/CoreDataVersioning/Articles/vmMigrationProcess.html#//apple_ref/doc/uid/TP40004399-CH6-SW1
Depending on your model changes, you may use "The Default Migration Process". When calling addPersistentStoreWithType:configuration:URL:options:error:, use the flag NSMigratePersistentStoresAutomaticallyOption.
Also, I'm sure that unfortunately you need one mapping model for each possible migration. If you have 3 models, you'll have to implement: 1 to 3 and 2 to 3. Core Data is not smart enough to do the intermediate steps automatically :(

How should I migrate my core data?

My core data store in the previous version to my app is different to the current one in the following ways:
Attributes missing
New attributes
Attributes which need changing
New entities
New relationships
Attributes which need moving between entities
How should I go about migrating my data? What I had in mind before looking into this was that I could just write code that could take the data from the previous model and put it in place in the new model.
I think the Core Data Model Versioning and Data Migration Programming Guide will cover these issues in some detail.

What is the difference between Model Versioning and Data MIgration?

I am new to core data, can anyone let me know the difference between Versioning and Data migration. When we do versioning and when we Data Migration?
Versioning is used just like versioning on apps to indicate different evolving variations of the same basic code except in Core Data the code evolving is the data model i.e. the entities, entity properties and relationships defined in the .xcdatamodel file.
Migration is what you perform on the end user's existing data in the persistent store in order to format/structure the store to work with the new version of the data model.
It works like this:
You release version 1.0 of your app which as a data model with a version of 1.0 as well. End user then use your app and save their data in a persistent store formatted/structure using your data model 1.0.
Then you release version 2.0 of your app and you make changes to the data model in the process e.g. you change a property name, add a property or add an entity. You would version the data model as well to something like 2.0 (the actual version names are arbitrary.) You then provide for either automatic or manual migration such that the end user data in the 1.0 persistent store file can be reformatted to the data model 2.0 format.
Every change you make to a Core Data model results in a new version. EVERY change.
Core Data has no concept of one model being newer than another though, it just knows they are different. Core Data will not use a store (database on disk) created by a model version different than what you have.
That's where Migration comes in, which is simply a process to tell Core Data how to get from one model to another with the data stored in a database made by a particular model. Core Data can try to guess (automatic migration) which for simple changes may work fine, but you can create more complex migrations by hand that carefully pluck data out of one model version and place it in a database of a newer model version.
When do you create a new model version? After you ship an application with a Core Data model to the App Store, you should immediately create a new model version for changes so the original model version that you can create a migration path for people who have the App Store version to a later version.
When should you create a migration? Basically any time you ship a new version to the store, you need to figure out a path from any earlier model that was in the store (and thus may be on someone's phone) to the latest data model version. As noted, if the changes are simple you can use an automatic version, but always test (keep each app store release accessible to build from so you can test out loading an older version then migrating to a new one).
By the way, an acceptable plan is simply to delete the existing database if the model has changed at all, as long as you can put anything the user did back in the database in some way (or if the user never put anything in at all, as in a caching database).

Iphone data migration on application update

I am working on an iphone application that uses sqlite to store application and user data.
This is the first version of the application and I wonder what I need to do to prepare for the future versions of the app.
Is this enough?
1. Make sure app version is correct in the XCode Project settings
2. Add a version number in sqlite file so that it can be read later
Lets simulate the next update!
1. New version of the app is downloaded to the device
2. The app reads the version number stored earlier in a sqlite table/field
3. App knows that application data has changed so it needs to update the sqlite and also
it wants to retain the user data (in app favorites & Notes).
4. Schema has not changed so it starts to insert the new application data into some tables.
5. It does not touch the user data tables
6. It updates the version number of the sqlite db.
Have I missed something that will come back and bite me when it is time for update?
So, when you develop an application that uses Core Data you start defining a Core Data Model. Each model will have its own version. You start creating the first and unique version of your model. You can find all the required, detailed, info at the official Apple Core Data Model Versioning and Data Migration Programming Guide
You should not handle database versioning through custom fields set in the database itself, use model versions instead via your Xcode project.
When updating the application, if you do not change the model version you do not have to worry about anything, since the database hasn't been touched. Every new update that do not change the model will require no effort from you.
If you need to update your model for the next update you have to do this:
Create a new model version
Set the new model version as the active version
Modify the model according to your needs
Here comes the interesting part. Your application will handle the migration between the models in two different ways: the simple way and the hard way.
Automatic lightweight migration
Following Apple's official documentation about Core Data Model Versioning and Data Migration, if your model has been slightly changed you can ask the application to perform an automatic lightweight migration. This step will update the existing database to the new version if these requirements are met:
Simple addition of a new attribute
A non-optional attribute becoming optional
An optional attribute becoming non-optional, and defining a default value
The lightweight migration process will handle the appropriate required step to migrate from one model version to another, if possible
Mapping model migration
If you can't perform an automatic lightweight migration you will have to manually define the step to update
the model versions to the new one, using Mapping Model Objects. These objects will define what the application has to do to migrate from model version x to model version y.

iPhone:Updating a Core Data Model in Future Versions of an App

I am releasing a Core Data based app and wondered what I need to consider if, in an update later down the line, I need to change the model.
How do I move existing user data on the device from the old data model into a new updated model?
Thanks
Generally, you'll have to consider nothing now but as soon as you change your data model, you'll have to employ Core Data's model migration tools. Read the Core Data Model Versioning and Data Migration Programming Guide.