Execute a code after data model migration in Core Data (MagicalRecord) - ios

I have to data models and a mapping model.
I would like to execute some code after the migration is done between my model v11 and model v12.
How can I do that? I'm using Magical Record.
I tried to do it in endEntityMapping from NSEntityMigrationPolicy, but it is an action that should be done after the entire migration, not in the middle.
Another idea I have is to save a flag in NSUserDefaults in any endEntityMapping and use it (and remove the flag) after my Core Data stack is setup by Magical Record, but this seems a bit workaround.

Related

How to keep your data when model changes?

I am learning entity framework. I am reading through some tutorials about initialization and how there are
CreateDatabaseIfNotExists
DropCreateDatabaseIfModelChanges
DropCreateDatabaseAlways
Custom DB Initializer
to choose from.
This makes me wonder, what does one do when they want to change the schema, but they want to keep the data they have?
I was just using sql directly, I could make temp tables, move stuff over, recreate the table with new columnns, move stuff back, etcv
What do you do when your classes and/or their relationships change in EF?
I think your looking for EF migrations:
https://learn.microsoft.com/en-us/ef/ef6/modeling/code-first/migrations/
for every schema change you create a migration, where you can add or remove tables or columns, or you can even run your custom script.
Each migration has an Up method, these will be applied if you run your migration, and a Down method this is used if you want to roll back to the previous migration for some reason.
With Update-Database you can apply all migrations, and with Update-Database –TargetMigration:{nameOfMigration} you can migrate to a specific version.

How to actually execute CoreData heavyweight migration

I am performing a CoreData heavyweight migration in my app. I have created a mapping model, made associated NSEntityMigrationPolicy subclasses, and selected the new model as the current. However, the migration does not appear to be happening. What do I need to do for this to actually occur?
If your model is not eligible for lightweight migration, then you have to do it manually. Simply this process can explained as reading records from old store and dumping them in the new store according to new model.
See here and here for more details
You have to manually switch off the automatic migrations from persistent store coordinator so core data would not automatically infer mapping model and use your custom created model in core data stack.
key: NSInferMappingModelAutomaticallyOption
value: false

Move a Core Data entity and its data into new Core Data model file through Migration

Is it possible to move a Core Data entity Car and its data in Model1 into a new Core Data model Model2 using migration? Model2 will also have a new CarOwner entity + other new relationships (so model file is different than Model1). Is this possible using lightweight migration or do I have to use custom migration? I'm using Magical Record to setup my Core Data Stack.
I have been using lightweight migration for years with success. So I don't have any custom migration mechanism in place. I want to ask first before I implement a new system so I can incorporate CD custom migration into my existing MagicalRecord Core Data stack.
EDIT: updated question to clarify that Model1 and Model2 have differences.
With the same xcdatamodel file and different versions you can use a Mapping Model file, but being different mom files i guess those are different stacks and migration will not work.
Model migration is only relevant if the model has changed-- meaning, if the entities contained in the data model don't match the entities saved in the persistent store file. Migration doesn't depend on what model file you use, it depends on the entity hashes contained in that model.
Meaning: If your new model file has exactly the same entities as the persistent store file has, you don't actually need to migrate anything. Just start using the new model file. However keep in mind that if you ditch the old model file and all of its old versions, you won't be able to migrate from older versions of that model any more.

Need some info on how to set up core data migration with a new 1-to-many relationship

Question regarding Core Data migrations:
The original model was just a single entity (Transaction) with multiple properties. The app could store N Transactions, and display them in a table.
Original Core Data Model (simplified):
Transaction:
property_x
property_y
property_z
The model has now been changed so that the new top-level entity is a TransactionsList entity, with a 1-to-many relationship so that each TransactionsList has multiple Transactions.
New Core Data Model (simplified):
TransactionsList:
property_a
property_b
transactions <-->> Transaction:
property_x
property_y
property_z
<- transactionList
The model has now been changed so that the top-level entity is a TransactionsList entity, with a 1-to-many relationship (transactions) so that each TransactionsList has multiple Transactions.
I'm having a problem finding any examples (either in Apple docs, or on the web) of how to set up a migration from the original configuration to this new configuration.
Lightweight migrations don't seem to work (since this change involves adding a new relationship).
I set up a mapping file, and tried to create a custom migration policy, but if I set breakpoints on any of the functions in it, they are never hit.
I turned on migration debugging, and it indicates that the migration succeeded:
"Automatic schema migration succeeded for store at "..."
However, if I look at the internals of the sqlite database, there are no database entries for the TransactionsList entity, and all the transactionList fields in the Transactions (which should be linked to the owning TransactionsList) are null.
Two questions...
1) Any clues as to why my custom entity migration policy might not be getting called
2) Any suggestions on the best way to set up this kind of migration?
Thanks.
You are correct that a light-weight migration will not work. Further, a heavy migration would be very expensive computationally and I would not advise it.
I recommend a two step approach:
Allow a light-weight migration to occur. This will cause your TransactionList entity to be empty.
After the migration, walk through your transactions and create TransactionList entities as appropriate.
This will be faster and easier to test/debug than using a heavy migration. You can test to see if a migration needs to occur using the -[NSManagedObjectModel isConfiguration: compatibleWithStoreMetadata:] method. This will let you know a migration is needed, then you kick off the migration and finally do the post processing.

How to migrate coredata model, deleting entity and saving into NSUserDefaults

How to migrate coredata model to new one with this feature:
The original model contains an entity "user" which contains only 1 row data. All I want is to remove this entity and save this data into NSUserDefaults.
This is not a lightweight migration. I'm using NSMigrationManager trying to save the results before it has been removed, but I haven't got it working yet.
Could you help me?
Thanks in advance.
It doesn't sound like you need to use any migration. Just retrieve the value and save it in NSUserDefaults and just ignore the entity from that point on. Maybe remove it in some future update using lightweight migration.

Resources