Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What do I have to do to get Core Data to automatically migrate models?

Tags:

core-data

I have read the documentation about automatic /lightweight migration for Core Data models - but I am having problems implementing it.

As I understand it the application should notice that the model it has and the model that exists on a device already are not the same. If you have only added attributes or relationships and similar simple changes then the model should be upgraded automatically.

Any pointers - do I need to set something in Xcode?

like image 635
Grouchal Avatar asked Jun 19 '09 14:06

Grouchal


People also ask

Can't find or automatically infer mapping model for migration?

If you set DM2 as the active version then run your app, a migration will run on your persistent store. If you then make another change to DM2, run your app... Boom! The issue is that your store has already been migrated to "DM2" but the data in the store doesn't fit into the model anymore.

What is mapping model in core data?

A Core Data mapping model describes the transformations that are required to migrate data described by a source managed object model to the schema described by a destination model. When you make a new version of a managed object model, you need to migrate persistent stores from the old schema to the new.

What is 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.


1 Answers

I've now found out that this is quite simple - once you know where to look.

In my AppDelegate I set-up the NSPersistentStoreCoordinator - and you need to add some options to this to tell it to handle auto-migrate:

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:  [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,  [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];  NSError *error; _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];  if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {     // Handle error     NSLog(@"Problem with PersistentStoreCoordinator: %@",error); } 

Then you need to do a little trick in xCode:

  1. Select your xcdatamodel file
  2. Select the Design Menu at the top - then Data Model - then choose Add Model Version
  3. Your xcdatamodel file will then get moved into a new directory with the same name as your xcdatamodel file but with the extension xcdatamodeld - there will be a second file in this directory with a 2 in the name. Select the new file and then Design->Data Model->Set Current Version (in Xcode 4 you do this)
  4. If you have already made the changes that have caused your project to be incompatible - take these changes out of the original xcdatamodel file. If you have yet to make the changes - then just edit the 2.xcdatamodel file (the one you just made current version).
  5. Now when you install this version onto a device that has the old model - it will automatically upgrade that model to the new model.

This seems great and as simple as I wanted - but I think you need to be careful during development as you change a model - otherwise you will have to create a new version for each change.

I think what I will do is that I will keep all of the changed files and then once I get ready to deploy my update I'll delete all the in-between files and just deploy with the oldest and latest models.


UPDATE (15/07/2011):

Thanks to @rockstarberlin for pointing out there is updated documentation at apple:

Xcode 4: Setting a Managed Object Model’s Current Version

Update: 8/19/2013 better link:

https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreDataVersioning/Articles/vmModelFormat.html

like image 184
Grouchal Avatar answered Sep 30 '22 22:09

Grouchal