CKSyncEngine how to handle new fields added to a CKRecord in future versions

I am seeking guidance on handling field-level schema changes in CKSyncEngine, specifically when introducing new fields in a subsequent app version.

The current CKSyncEngine documentation (https://developer.apple.com/documentation/cloudkit/cksyncengine) and the GitHub sample (https://github.com/apple/sample-cloudkit-sync-engine) provide clear instructions for managing changes to existing CKRecords. However, I am uncertain about the best approach for handling newly added fields in a new version of my app.

For example:

  1. In version 1 of my app, I have a CKRecord named User with a field called name.
  2. In version 2, I plan to add a new field, phone_number, to the User record. When version 1 (e.g., installed on a user's iPad) and version 2 (e.g., installed on the same user's iPhone) sync using CKSyncEngine, version 1 is unaware of the phone_number field.

My concern is how to ensure version 1 handles this scenario gracefully without blocking other sync events.

Additionally, when version 1 on the iPad is later updated to version 2, there will be no new sync events unless the "phone_number" field is modified again. This could result in the "phone_number" field never being synced to the iPad.

Could you please advise on the best practices for handling such cases to ensure seamless synchronization across different app versions?

Thank you for your assistance.

Answered by Frameworks Engineer in 803581022

Starting with forwards compatibility, you generally have two options here:

  1. Store all values on CKRecord and perform a migration on an application update. Do note CKRecord and CKRecordValue are NSSecureCoding compliant.
  2. On application update create a secondary temporary sync index and refetch all records.

Depending on your solution to the above, you may either:

  1. Implicitly ignore unknown fields on CKRecord noting that values are accessed by explicit keys therefore your application should naturally ignore unknown fields.
  2. Use desiredKeys to only fetch the fields your application can handle.

There are performance considerations here so carefully weigh your requirements when deciding how to handle these cases.

Starting with forwards compatibility, you generally have two options here:

  1. Store all values on CKRecord and perform a migration on an application update. Do note CKRecord and CKRecordValue are NSSecureCoding compliant.
  2. On application update create a secondary temporary sync index and refetch all records.

Depending on your solution to the above, you may either:

  1. Implicitly ignore unknown fields on CKRecord noting that values are accessed by explicit keys therefore your application should naturally ignore unknown fields.
  2. Use desiredKeys to only fetch the fields your application can handle.

There are performance considerations here so carefully weigh your requirements when deciding how to handle these cases.

CKSyncEngine how to handle new fields added to a CKRecord in future versions
 
 
Q