My CoreData Migration (Test)

A walkthrough lightweight and heavyweight migration

Philipp Weiss
Oct 21, 2019 · 4 min read
Image for post
Image for post

When I worked on CoreData I was usually able to perform a lightweight migration to a new model version. But whenever it came to a more complex use case I struggled to find a solution.

That is why I wrote this piece.

But first, what’s the difference between a lightweight and a heavyweight migration?

LightWeight Migration

To me, this means easy use cases like adding and renaming variables or creating new relationships and objects.

HeavyWeight Migration

Starting with the test of a LightWeight Migration

Let’s start with a simple CoreData model. We have a person that has a name, a surname, and the information of whether they’re a teacher (as a Bool).

Image for post
Image for post
Model 1

However, we soon realised that this model was not sufficient for our new purpose. The new model changed the variable names and is adding the variable “age”.

Image for post
Image for post
Model 2

Since this modification is done with a lightweight migration we have now finished creating the new model version. But we’ll feel a lot better if we test the migration with the help of XCUnitTests!

Here’s the code to perform this:

Mark 1:

Load the ManagedObjectModel and initialise the NSManagedObjectContex with the PersistentStoreCoordinator containing the SQLite file URL.

Mark 2:

Add some test data for the migration. In this case, it is a person who is a teacher.

Mark 3:

Load the ManagedObjectModel that is the migration destination. For the lightweight migration, we have to set the following options:

  • NSInferMappingModelAutomaticallyOption
  • NSMigratePersistentStoresAutomaticallyOption

This is so CoreData knows it should try an automatic migration.
Then we create the PersistentStoreCoordinator and add a PersistentStore. It’s important to use the same URL as we did with the first model version.

Mark 4:

We can now test the migration and we can see that the variables have been renamed and “age” has been added.

The HeavyWeight Migration

Since we know whether each person is a teacher or not we want to split them into teachers and students. To do this, we need to create a new objects Person(teacher: true) -> Teacher & Persons(teacher: false) -> Student.
We will do so by adding a new CoreData Model Version 3.

Image for post
Image for post

To execute this Migration we will need a Mapping Model and a Custom Migration Policy. You can delete all but one of the Entity Mappings. Now we need to add a Custom Policy for the migration. Make sure to add the project name in front of the Custom Policy class name.

Image for post
Image for post

Next, we need the EntityMigrationPolicy.

MARK 1:

Check if the entity is a person.

MARK 2:

Fetch the names from the entity

MARK 3:

Create a teacher or a student and add the values again.

Testing the HeavyWeight Migration

MARK 1:

Just as with the LightWeight migration, we will read the old model and create the ManagedObjectContext.

MARK 2:

Here we add the new elements that should be migrated

MARK 3:

Here we migrate to the new model version. Therefore, we need to get the mapping model and create the MigrationManager with the old and the new model. Then we run the migration with the help of the manager and the mapping model. Then we load the new ManagedObjectContext.

MARK 4:

Finally, we add some tests to verify that the migration was successful.

Better Programming

Advice for programmers.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store