Modifying the Core Data Model Requires New Version Every Time? - ios

I've been searching around and let me get this straight, every time I change the attributes of my entities, I need to create an entirely new version of my model? I understand that the SQLite database is now out of sync with my data model, but can't I just delete the sql files and re-run my simulator? This is what I've been doing, but it doesn't seem to be working.

You are correct, any changes to the core data model must be made in a new core data model version. You can avoid having to do this for development builds by resetting content and settings in the simulator, or deleting the old app version on a device before installing. For store builds though, you must correctly manage your model versions so that user's will have their persistent store properly migrated to a new store with the new model. Versioning is required so that lightweight migrations can be performed, without you having to write custom migration code. If you don't want to version your model, you are bound to writing code to properly migrate your entities. This can be a lot of work and difficult to maintain, you'd rather use lightweight migration and versioning.

Related

Adding inverse relationship in Core Data to older model versions

I'm trying to clean up a project I have that uses Core Data. The data model has 20 different versions. Each version throws a warning about 'The inverse relationship for UserMO.specialties does not reciprocate an inverse relationship'.
Can I go and add inverse relationships to my older and current model versions, without corrupting anything? Or do I need to create a new model version, for which a lightweight migration will be performed?
You can't change older models and keep using them with the same data. You'd have to create new versions of the models with the fixes, and migrate data to use them. But model migration requires having the previous model version, so you'd still have to keep those old models around. In short: You're stuck with those models, with their warnings, unless you decide that you're not going to support even migrating data from them to new versions any more.
The only time you shouldn't create a new model version when editing your models is if you're working locally and you are the only person who has access to the changes.
For this problem in particular, just creating a new version, tagging that version as the one to use, and letting the system do a lightweight migration will be fine.

How the Core Data Migration will work for two projects?

I'm working on an app which using core data (one app is already live on the AppStore). OK, now I want to make it fully functional for iOS8 and client also asked me to make a good change in UI and its structure so I started a complete new project and decided to code it my self. Everything works fine, then client emailed me and confirm that, new version of app should store & fetch existing values from the database if existing app will get update. I feel bad here.
I know core data migration is possible ( I read this too, but there's some glitches in my mind about this concept.
As I told, I started a new project though is it possible to add a new version of the model?
Our entities and attributes names are not same. I named it the way I want.
Our model name is same. e.g. Somename.xcdatamodel
My app will update to the existing app on the AppStore.
How I can migrate the existing core data database to the new one?
Is this possible? How?
Any suggestions and help on this would be appreciated.
Note:
I read this question, Core Data Migration: How to delete the Core Data stack? and found that there's no issue if I delete the previous model? What you suggest?
If you need to migrate and keep the existing data, you should read more about writing custom policy Core Data Versioning Guide. Read this guide completely to get to know which category your app migration falls in.
1. Lightweight migration.
2. Or you have to write your own custom policy.
As far as i can tell from the details you provided it looks like it might be a lightweight migration for which you do not have to do anything you can just add a new version to xcdatamodel and mapping models. If not then you have to write your own custom policy and mapping models.
Also make sure you test upgrade properly.

Consideration of multiple datamodel versions with Core Data light weight migration

I'm new to Core Data migrations. I read a tutorial about light weight migration. The scene is like this:
I created a data model, it is version-1.
So I have to add an attribute in my entity, I did this using a light weight migration. Now the data model is version-2.
Sadly, I need to add another attribute again. I still use a light weight migration to do that, now the data model is version-3.
If my user updates quite often, it is alright. But what if my user has data model version-1, and updates the app directly to data model version-3? Do I need to write code to handle the migration from v1 to v3, or is it handled automatically for me since I used light weight migration?
Your app needs to be able to handle all possible migrations that might happen. If the current version is the third, it must be possible to upgrade all previous versions to version 3.
This doesn't mean you actually have to write code for the migration. If automatic lightweight migration is possible, then it will work, without any custom migration code. Whether that works depends on how the model has changed. If a v1 --> v3 migration is possible with automatic lightweight migration, you can use that. If it's not possible with automatic lightweight migration, you need to handle it yourself. The answer depends only on how similar version 1 is to version 3, and has nothing to do with the fact that there was also a version 2.
In my experience this works automatically. It's fairly easy to test, also, so I would recommend that. Create v1, install app on device, add some data to the app. Create v2, v3, then run app on same device. Does it work?
Also, you need to be careful when writing new app code that you don't assume that the new fields have valid data in them for any existing records in the database at time of upgrade.

iOS CoreData Migration using Custom Mapping Models with multiple historical database versions

I have an app and many history versions of the database.
Our users are typically "once in a year" users, so this means you can never be sure which version of the database their app is running on.
Now in my new version of the database I need to do some custom migration.
The method I use to do this is described in this tutorial: http://9elements.com/io/index.php/customizing-core-data-migrations/
To summarize: I have to make Custom Mapping Models so that I can write my own migration policies for some fields.
Now when I create a Custom Mapping Model, I have to select a Source "xcdatamodel" and a Destination "xcdatamodel" (where "destination" is te new version of my database).
My question is, if I want to do this custom migration from all possible versions, do I need to create multiple Custom Mapping Models, all with a different source, or is there a smarter way to do this?
Or is CoreData smart enough to recognize this?
The short answer is yes; you need to test every migration from every source model to your current destination model. If that migration requires a custom mapping then you will need to have a mapping for that pair.
Core Data does not understand versions; it only understands source and destination. If there is not a way to get from A to B then it will fail. If it can migrate from A to B automatically and you have the option turned on, then it will. Otherwise a heavy (manual) migration is required.
Keep in mind that heavy migrations are VERY labor intensive and I strictly recommend avoiding them. I have found it is far more efficient to export (for example to JSON) and import the data back in then it is to do a heavy migration.
It is enough to have a consistent sequential series of migration models up to the current version. Core Data is "smart" enough to execute the migrations you tell it to migrate in the given order.

Making Changes to Data Model with SQLite iOS

I'm reading data from a pre-populated sqlite database using CoreData. Everything is fine and dandy, except when I decide that I want to add another entity to the CoreData model (and another table to the sqlite database). I've tried several things, including making the changes to the model in Xcode, removing the sqlite database, and then hoping it generates a new database like it has in the past.
However no matter what I've tried, I get this error:
The model used to open the store is incompatible with the one used to
create the store.
Maybe I'm not doing this the right way, but it seems like Xcode makes it difficult to change the data model, which doesn't make sense to me when you're developing an app.
In general, if you delete your app and recreate it, the boilerplate code that comes with the project will generate you a new (and like you say, compatible) database.
Also, CoreData is intended to be used as an object graph with persistence; what it does with the generated SQLite DB as a result of providing this is its own business.
If what you're saying is: 'I have a valid CoreData store file and model, and I'm trying to hand-upgrade the store file to match a new model', you're breaking the rules of the framework. To morph an incompatible store to a new model, you need to use versioning and mapping models (without directly touching the SQLite DB).

Resources