Core Data custom migration without migration policy? - ios

I am changing the model of my Core Data app in a big way for the next update, and custom migration is definitely needed. After reading Apple's docs on migration policy, I find it very confusing and wondered if there is an easier way. I am thinking, why not just bring up the data in the old context/model, and bring up a blank context with the new model, and copy object one by one into the new context/model and perform any needed logic in between? This way, I can even make use of logic in my NSManagedObject subclasses to construct data in the new model instead of working with the mechanism in migration policy. Has anyone tried something like this with any success?

Related

Do we need to add new version to core data if we add new tables into it?

I have an existing core data project now I want to add some more tables into it so my question is do we need to add change current version of CoreData and add new version to it ? Also my app is already live. Now I want to publish another version of application by adding some more tables to it.
https://developer.apple.com/documentation/coredata/using_lightweight_migration
Core Data Migration
In order to follow core data migration we should keep on versioning our .xcdatamodeld file. Also to address new changes we should not make any changes in existing data model. Instead we should create a new version of .xcdatamodeld and perform changes there. We should follow core data migration if there are changes in:
Entity -
Add a entity,
Remove a entity,
Renaming a entity.
Attribute-
Add an attribute,
Remove an attribute,
Renaming an attribute,
Relationship -
Add a relationship ,
Remove an relationship ,
Renaming an relationship .
It is better to make an explicit migration, especially if you have your app live and there is user data in the field.
Core Data has a method for it, the
Lightweight Migration. Core Data can typically perform an automatic data migration, referred to as lightweight migration. Lightweight migration infers the migration from the differences between the source and the destination managed object models.
If you want to adapt also parts of your old model, when they are affected by your changes you may use the Heavyweight Migration
There you may migrate the old user data and you can change your old model if it is affected by your changes and your changes are logically complex.
Nevertheless if there are no changes which affect your old model you may also only add a table, but I personally migrate.....

App is getting crashed after updating from appstore becuase of Coredata migration

My app is working perfect for the first release v1.
In second release v2, i made a mistake while doing coredata migration - I accidentally given a renaming ID for an entity (It was empty before) in my coredata. Becuase of that the app was crashing when updating, but it is working when freshly downloading v2 version.
Now, what should i do in my next release v3, to fix this crash?
If i am replacing the renaming ID of the entity to empty, updating an app from v1 -> v2 -> v3 will be working.
But if a user freshly downloaded v2, it will get crashed again.
Please give me some workaround for this issue. Thanks in advance.
Use core data Lightweight Migration. Lightweight migration is especially convenient during early stages of application development, when you may be changing your managed object model frequently, but you don’t want to have to keep regenerating test data. You can migrate existing data without having to create a custom mapping model for every model version used to create a store that would need to be migrated.
Core Data Must Be Able to Infer the Mapping
To perform automatic lightweight migration, Core Data needs to be able to find the source and destination managed object models itself at runtime. Core Data looks for models in the bundles returned by NSBundle’s allBundles and allFrameworks methods. If you store your models elsewhere, you must follow the steps described in Use a Migration Manager if Models Cannot Be Found Automatically . Core Data must then analyze the schema changes to persistent entities and properties and generate an inferred mapping model.
For Core Data to be able to generate an inferred mapping model, changes must fit an obvious migration pattern, for example:
Simple addition of a new attribute
Removal of an attribute
A non-optional attribute becoming optional
An optional attribute becoming non-optional, and defining a default
value
Renaming an entity or property
Source : https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreDataVersioning/Articles/vmLightweightMigration.html

Is possible to use several Core Data models inside an app?

We have an app that it's already in production with a Core Data model that we need to replace. There has been a lot of changes in our server side and we want to update the model to reflect those changes and new functionalities.
Instead of performing a custom Core Data migration we're discussing about creating another model from scratch and get rid of the old one. We do not need to persist any of the existing data in our actual model because it's all available in our server, so when the user needs it again the app will download it when requested.
Is it possible to create a new model, tell the app to use it and safely delete the old one? Are there any other options to solve this problem?
You can have as many models as you want. If you are using Apple's template for Core Data Stack, then you should alter managedObjectModel and persistentStoreCoordinator to reflect new name for your model and file.
If you don't need any of the legacy data locally then modifying these 2 methods after preparing you new model with new model name should be enough.
Another option is to auto-migrate your existing data through new model version, but it does seem to be required in your case.

CoreData - Update model class instead of creating new

I am using CoreData in my iOS application. I face a problem most of the times while creating NSManagedObject classes.
This is what I do:
I create an Entity in .xcdatamodeld file.
Create attributes and relationships.
Choose option Editor->Create NSManagedObject Class to create .h and .m classes.
In .h and .m classes, I create some of my custom methods for fetching/saving objects.
So far so good. But afterwards in future if I have to change some attributes, I repeat step 2 and 3. But this time all of my custom code written in step 4 are removed automatically.
So my question is how can I update the existing classes? Instead of using option Editor->Create NSManagedObject Class which removes all my custom code.
Any help is appreciated.
Update:
Tested both approaches (Categories and Mogernator) and looks fine to me. But I have choosen Categories of being a pure Xcode approach. I don't want to take the risk of any 3rd party which may break in future due to XCode updates or can cause problem of data migration.
Thanks to #Tom Harrington, and #Valentin Shamardin for guiding me :)
To make some additional methods or other stuff for your Core Data model classes you have to create Categories. This approach is used by Paul Hegarty in Core Data lections.
The best way to handle this is to use mogenerator to generate your model classes instead of having Xcode do it. With mogenerator you get two classes for each entity:
One that is re-generated every time you rebuild the model classes
One that is a subclass of the other, which is only generated the first time you build model classes and which mogenerator never changes afterward.
As a result you can put all your custom code in the subclass, and no matter how many times you re-generate your model classes, your code is never overwritten.
Whenever yo change or update your core data object model it becomes incompatible and cannot be open and as a result it gives crashes.
For this you need to perform Core Data Model Versioning and Data Migration.
Versioning is nothing just only provides you which model version is application going to use. Changes and update in core data model like modifying any attribute of entity or adding new entity. It is related with Core database model. Consider your application going to use 1.0 ver and using database model of 1. if u have some changes in database model its version increases and now you application going to use next version ie 2 of core database model
The details refer to this Apple Doc for Core Data Versioning
Also this will result in old Data loss. For this you need to perform Migration Process.
During migration, Core Data creates two stacks, one for the source store and one for the destination store. Core Data then fetches objects from the source stack and inserts the appropriate corresponding objects into the destination stack".
Please refer to Migration Process details on Migration on Raywenderlich
You need to use NSMigrationManager class and

Deleting Entity Column from Model - Auto Remove Scaffolding?

I need to remove a column from the database in EF 4.3. The database has updated successfully, but the scaffolding is still there for the CRUD views and errors when trying to access them. Is there a way to auto remove scaffolding once the model changes, or do I have to manually delete all instances?
I'm not sure, since I don't know what scaffolding generator you're using. If it's the one that "comes with the box", I'm pretty sure you have to delete the CRUD manually.
The scaffolding generators I'm familiar with are just generators. They don't maintain an awareness of what's been generated, so they don't respond to data model changes. It's a a oneway process.
OTOH, that also means you can probably "eliminate" the scaffolding gunk by rerunning the generator. You'd have to save the customized bits you've added to the scaffolding output, of course, but that may be simpler than deleting what's no longer needed.

Resources