Search code examples
iosobjective-ciphonecore-dataensembles

Ensembles and Core Data Light Migration


I am currently doing some tests with Ensembles, specifically testing Core Data light migration.

My current configuration is as follow:

  • Device-A running my app with data model 1
  • Device-B running my app with data model 2
  • data model 2 is based on data model 1 with one additional string property, which is optional

My scenario is as follow:

  • At the beginning, running my app with data model 1 on both Device-A, and Device-B, everything synced fine using Ensembles (iCloud configuration)
  • On Device-B, install and run my updated app using data model 2
  • On Device-A, keep running my old app using data model 1, and add a new record
  • The result: the new record added on Device-A is uploaded to iCloud and then synced to device-B

My question: can I configure Ensembles to prevent it from uploading changes to iCloud in case that related data model is not the latest one? (i.e. in my case, Device-A uploads an object based on data model 1 while iCloud is already based on data model 2)

Thanks in advance!

UPDATE 1:

Drew, thank you very much for your answer. I definitely agree that uploads can't (and probably shouldn't) be prevented as Ensembles is a decentralised, peer-to-peer system.

In the ideal case, I would like that the device with the new data model will ignore data that is based on the old data model. (in a similar way to the existing behavior where the device with the old data model will ignore any data based on the new data model). Is that supported?

If not, please consider the following scenario as an example:

  • The old data model has an entity called 'Book' with two properties: title, and author (both fields are non optional)
  • The new data model has a new optional property called titleFirstLetter that should hold the first letter of the title field.

Currently, when Ensembles is not involved, I have full control when saving new NSManagedObject to the persistence store. Therefore, the updated code of my app which responsible for adding a new book, will make sure to extract the first letter from the title field and save it to the new titleFirstLetter property. (i.e. a book titled Catch-22 will have C in the titleFirstLetter property when book is saved).

In addition, when light migration occurs on the core data stack, I detect that, and perform a one-time procedure where I iterate all existing books in the database, and set the titleFirstLetter according to the title value. From this point and on, the database is consistent and valid, while the new code will ensure that future books added to the database will keep database valid.

Regarding Ensembles, if I don't have any control on old data coming from devices with older data model, how can I fill the new property of titleFirstLetter, if my code is never being called?

Thank you for your kind assistance!


Solution

  • You can't prevent it, no. Ensembles is a decentralised, peer-to-peer system. There is really no way for one device to know the current state of another device, so you couldn't prevent an upload.

    The updated device should be capable of handling the old data from the other device. The device with the old model will ignore any data based on the new model, until it too is updated. Then it will merge all of that ignored data.

    It is best to avoid migrations where possible, and stick to simple stuff like adding properties or entities, rather than tricky refactors. If you need to make a lot of changes, consider simply starting with a new ensemble (e.g. change the ensembles identifier).