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.
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.
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.
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.
What approaches do I have available to solve this problem?
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.