swiftcore-datacloudkitcore-data-migration

How to handle data migration when using CloudKit?


General problem

I have an iOS app which uses Core Data with CloudKit and I reached the point where I need to evolve the schema and migrate existing data.

Schema changes

What I need is adding a new entity which as a 1 to many relationship with an existing one. This can be easily done with lightweight migrations.

Data changes

At first launch with the schema, I need to create 1 entry for the new entity and link it with all the existing related entities.

The solution I found is to keep a collection of data migrations in my code and have a dedicated Migration entity in my schema to store a log of already executed migrations.

This works in most cases, except when the user has some data in CloudKit which is not synchronised yet with the device. In this case I would run the migrations only on the local data and when new one comes from the sync it would not be migrated.

Failed approach

I've looked into listening for NSPersistentCloudKitContainer.eventChangedNotification but at lest to my knowledge these notifications don't have enough data to determine if the sync is complete for all entities and I haven't been successful with this approach.

Question

What approaches do I have available to solve this problem?


Solution

  • What I ended up doing was give up on having a proper migration list which only runs once.

    I wrote my migrations so that they can run multiple times and I execute them:

    To manage duplicates created by migrations executed before CloudKit could sync, I have some deduplicating migrations which also run with the others.