CoreData migrations without versioning - ios

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.

Related

Modify CoreData twice during development

I've gt a question to ask. Currently my production CoreData version is 1.0. Then , since i've gt a new class/property to add, i've increased version to 1.1 and released this version for tester.
Now, I need to add another property to CoreData.
1) So, should I create a new model version or I can straight away modify current CoreData(v1.1).
Note that the build with v1.1 CoreData hasn't been released to production yet..just to tester.
2) If need to add new version (v1.2) to accommodate the new property, will it have any affect when i released it to production build?
3) If can straight away modify, will current development version that tester has installed crash when they update to new version that has the new property added?
You can modify v1.1, but then tester will have to delete the app, as the app may not be able to open the coredata or have inconsistencies. To avoid this, tester will have to delete the app,and he might miss issues(if any) due to this structure change, to catch only in production. So you should be changing the version.
It wont cause any issues, if the versioning and migration is done properly.
Yes, there could be inconsistencies and instances where the app won't be able to open the coredata.
In order to avoid CoreData versioning for testing purpose you can modify the current CoreData version and tell your tester to delete the previous build before installing new one.
Otherwise you have to perform migration every time you change the DB schema in order to avoid inconsistency.
You can do the versioning before sending it to the production environment.

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

Core Data Lightweight Migration - when to version?

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.

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.

Resources