Nic Hubbard
Nic Hubbard

Reputation: 42173

Migrate Binary Data objects to Core Data Entities

I have an app that uses Core Data to manage Entities that we call lists. Each list has an offlineData property which is of the type Binary Data. The Allows External Storage option is true for this.

This entity holds an array of custom objects using the following method:

NSArray *customObjects;// My custom objects that have been added
self.list.offlineData = [NSKeyedArchiver archivedDataWithRootObject:customObjects];

This will save the objects to a Core Data blob since all the objects are are using initWithEncoder: and encodeWithCoder:.

When users then want to view the list we do the opposite:

NSArray *items = [NSKeyedUnarchiver unarchiveObjectWithData:self.list.offlineData];

The Problem

This seemed like a great solution at first (obviously stupid now) because we could easily add additional properties to the objects, etc. However what we didn't anticipate is users adding thousands of objects. This has caused:

Solution?

The solution I am thinking of would be to migrate all the custom objects to Core Data entities. This would be a To Many relationship between the list entity and the object entity.

This seems like it would solve the problems outlined above, but I am not 100% sure.

Does anyone have advice on this, and if this is the best way to "migrate"?

Upvotes: 0

Views: 397

Answers (1)

Tom Harrington
Tom Harrington

Reputation: 70976

Migrating to a new entity as you describe should solve your problem nicely. In your new data model version, you'd create the new list item entity, delete the existing list property, and create the to-many relationship you describe.

You can't rely on automatic migration for something like this though-- you'll need to customize the process. I described the process in a different answer that mostly applies to you. You'll have to create a mapping model and a custom subclass of NSEntityMigrationPolicy. It's not complex but it's unfamiliar to most iOS developers.

Unlike that other answer, you'll need to implement the createDestinationInstances(forSource:, in:, manager:) method in your NSEntityMigrationPolicy subclass. For instances of your entity, this is where you'll create a bunch of list item objects. Unarchive the existing data blob and create new instances.

Keep in mind that this means you'll have to unarchive all of the existing list blobs. It might take a while to migrate for the scenario you describe. But you only have to do it once per user. Make sure to show some informative information on the screen so people know what's going on, and make sure to test the migration with a list that would be large enough to be a problem.

Apple's docs on custom migrations will also probably come in handy.

Upvotes: 2

Related Questions