Confused by how to setup my .xcdatamodel for versioning - ios

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

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.

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.

Unreleased xcdatamodel versions and lightweight migration

If I have multiple unreleased xcdatamodel versions between release A and release B, will lightweight migration still work once I release to the public if I delete the unreleased versions?
Here's a more discrete example:
xcdatamodel version 1.0 --> Release to public A
xcdatamodel version 1.1 --> unreleased (based on v1.0)
xcdatamodel version 1.2 --> unreleased (based on v1.1)
xcdatamodel version 1.3 --> Release to public B (based on v1.2)
I want to make sure that when I submit release B, users coming from release A will be migrated properly. Or is this a completely terrible way to go about it? I understand that if I didn't care about the data on my testing devices, I would just base xcdatamodel version 1.3 on version 1.0 and put everything new in that version - I just don't want to lose the data on my testing devices that have had versions of the app with v1.1 and v1.2 already on the device.
Thanks!
Assuming that the format used for existing user data can be converted to the current format via automatic lightweight migration, it doesn't matter that you created internal, unreleased versions.
What you need to include in the released app: every version that any user might be using. In your case it looks like people would only have 1.0-formatted stores, so there's no need to include 1.1 or 1.2. If that's not the case-- i.e. if there's a user out there somewhere who might have version 1.1 or 1.2 data-- then you need to include them.
So, as long as the 1.0 --> 1.3 changes work with automatic lightweight migration and that no users have 1.1 or 1.2 format data, you could just delete the intermediate versions.
Lightweight migration will only work with certain types of model changes. The best thing is to test this thoroughly. You can safely do the following:
Add new optional attributes or relationships to an entity
Add new required attributes to an entity with a default value
Change an existing optional attribute to required but with a default value
Rename an attribute or relationship or entity and specify the old name in the "Renaming ID" field of the core data utilities pane tab.
The Core Data Model Versioning and Data Migration Programming Guide lists more operations, but again you should test all this.

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.

Is the project "cleaned" on the users device when he/she downloads an update from the app store?

I use Core Data. During development when I add a new model version, I need to clean my project in xcode before I build it, so that a migration to the new model version takes place.
So when my users update their app is their app "cleaned" as well before the first start?
Or do I need to force migration in another way?
To be more precise: When I just build my new app version (with a new core data model version) in xcode and run it on the device it crashes whenever I try to access new properties of my managed objects (since it did not migrate the sqlite DB to the new model).
Yes, in the way you understand "cleaned", the apps of your users are put into an executable state. All data stored in Core Data's persistent store will be migrated to the new store and will be available as before.
In fact, that is the whole point of Apple's migration scheme. As pointed out by FR, read the documentation.

Resources