Core Data Lightweight Migration - when to version? - ios

Can I do the following?
Start with v1.0 of an app. Version data model, designate new version as active schema
Set correct options in appDelegate for creating NSPersistentStoreCoordinator using lightweight migration
Make simple changes to the model and update classes. Compile and verify that everything works.
Make another change to the data model without changing the version, and again update the classes
Of course when I run, the data model will be incompatible since I have changed it without versioning. But since I will not be shipping the intermediate version, my suspicion is that the data migration should work fine when updating from v1.0 to the double-updated data model.
Is this accurate?

It will work as long as the following are true:
You have created a new model version for each of these steps; so in your example above you should have three at the end: original, intermediate, final.
The app must be able to do a lightweight migration from 1 to 3. If it cannot it will not go through 2 if the data on disk is still in the structure of 1.
If all of that is true then it will work. And you can even go so far as to not ship v2 in the final build (although they are small and it is usually not worth the effort).
During development my recommendation is to always keep the v1 data around, only change v2 and remigrate every time you need to adjust v2. Then there is no intermediate to deal with. However that is not always possible when dealing/working with beta testers.

Related

CoreData migrations without versioning

Right now I use versioning to make any changes in a database. But it brings some problems. For example it's hard to merge a feature branch with a new db version into a master/dev where somebody also added a new version.
So my question:
Is it safe to change db in a single xcdatamodel without adding new versions? I tried so and it works but everywhere on the internet I see warnings that you must not do that.
iOS9+.
I found this: https://stackoverflow.com/a/37264096/5328417 but it's without a proof
As #pbasdf noted, since iOS 9 you can do a lightweight migration without adding any new model version. Source model (previous model version) is cached to store and used as a last ditch effort during lightweight migration.
I am using this feature in my own apps successfully. Although I was not able to find this documented. Just that WWDC video (18'15 Model Caching) mentioned. This is exactly the reason why Core Data is so mysterious sometimes..
If your app is in development stage then you may use one model without versioning.
But if it is release on the App Store then you have to create the versions when you make changes (such as adding a new attribute, adding a new entity, renames attributes etc.). Otherwise, Core Data won't perform lightweight migration.

How to manage versions of Data Model Schema versions

I am having an app on app store. I have to update model version after every 2 months on average due to updates.
I have 7 versions right now and they will definitely increase in future.
I have some questions:
How I can efficiently manage this
Can I delete my older version?
How many versions I can add?
How I can efficiently manage this
I recommend naming the model versions based on the release they are associated with. It helps to keep things straight.
Can I delete my older version?
Yes but not recommended. If someone is still using an older version of your app they will fail to migrate if the source is not there.
How many versions I can add?
Unlimited. However you should only have a version for each production release where data structure has changed. If you have intermediate versions that only exist for development, I would recommend removing them as they don't impact the user.
Lastly, make sure you have a unit test that migrates from every old version to the current version. Core Data is not temporal and will not go from 1 to 2 to 3. It only understands source and destination. Can your app currently migrate from 1 to 10? If not, you need to address that.
How I can efficiently manage this
Continue to increase versions when you add changes to model.
Can I delete my older version?
Yes you can. Just open data model in finder and delete version, re-add data model to project. Also make sure you handle NSPersistentStore creation fail (if merge is unsuccessful).
How many versions I can add?
As many as you need.

Confused by how to setup my .xcdatamodel for versioning

I am reading the Core Data Model Verisoning and Data Migration Programming Guide and am confused on how to set up the initial verison number.
I have an existing app in which I did not set it up for Core Data versioning. In addition, I am using Magical Record. The current version of the app is 1.3; I am ready to release 1.4 with some minor changes, and I want to change one of the Core Data entities (add new attributes) in release 1.5. I absolutely need versioning so my users will not lose any existing data. I assume I must set up the current verison to enable Lightweight Versioning for release 1.5.
The question is: does the Core Data version have to match the app version? or is that the common way for versioning to work?
Magical record has a convenience method for this. In your AppDelegate where you setup magical record use.
[MagicalRecord setupCoreDataStackWithAutoMigratingSqliteStoreNamed:#"storeName"];
Alternatively click on your core data .xcdatamodeld then top bar Editor > Add Model Version

Combining or skipping version of the core data model

During development of a new feature, I have versioned my core data model a few times, always using lightweight migration. I am working on v1.5 of my app and now have versions 1.5.0, 1.5.1, 1.5.1, etc of my core data model. Only the final version is going to be used by a deployed product - to put it another way, had I been better able to predict the model I would end up with, my v1.5.0 would have looked like v1.5.99.
Is there some way to consolidate the intermediate versions, so that the migration is one-step? If I don't do this, will the migration run multiple times, and will there be a performance impact?
I am considering restoring my v1.4 version and manually re-creating the final model version as the only new version, but am not looking forward to re-adding all of the other code that has been updated in the same branch.
If (1) you don't have any data stored with the 1.5.0, 1.5.1, etc. versions, and (2) migration from 1.4 to 1.5.99 can happen automatically, then you can just remove the intervening versions from your data model.

When would you use Entity Framework code first

I have seen a number of demos from 'respectable' individuals demonstrating the merits of the code first feature for Entity Framework. All of which looks like mouth watering toys!! but one thing strikes me...
Other than in development when would a code first scenario benefit my project?
Having the framework build the database for me seems awesome in a development and testing (portability!!!!) stage of the project but when I update the live project I would not want any of this to occur.
Knowing when the framework is about to overwrite my database and inserting my static data back in seems like a reasonable idea (for test scenarios) but all the demos I have seem put the code to construct this in the EF assembly.
EF Migrations is going to make this clear??? Maybe. Anyone have views on why I should be using this code first?
In my opinion automatic database generation is only for development and testing. Once you move your application to a production environment you should make sure that this feature is turned off. This is especially important once you decide to deploy new version of your application.
EF Migration will perhaps change it by I'm sceptic. I would never let some automatic black box touching my production data. We already had very bad experience with VS Database tools so we never let them working with real data directly - we only let them generate script for us, we precisely test these script and manually execute these scripts on the production. Sometimes it even requires adding some additional migration scripts with temporary tables. That is exactly the approach which should be in my opinion used with EF as well. Let code first crate a new database in your dev environment, use a tool to create difference script for you against the old database, test it and deploy it.
But most importantly: Any upgrade or change on production database should start by backup so if tool fails you can always go back.
Choosing code first / database first / model first is based on the way how you like to develop application and on other requirements you have.

Resources