Collaboration of iCloud Drive document with CloudKit-based live sync

In Apple Numbers and similar apps, a user can save a document to iCloud Drive, and collaborate with other users. From what I can gather, it seems to use two mechanisms: the document as a whole is synced via iCloud Drive, but when a collaboration is started, it seems to use CloudKit records to do live updates.

I am working on a similar app, that saves documents to iCloud Drive (on Mac, iPad, and iPhone). Currently it only syncs via iCloud Drive, re-reading the entire (often large) document when a remote change occurs. This can lead to a delay of several seconds (up to a minute) for the document to be saved, synced to the server, synced from the server, and re-read.

I'm working on adding a "live sync", i.e. the ability to see changes in as near to real-time as feasible, like in Apple's apps.

The document as a whole will remain syncing via iCloud Drive. My thought is to add a CloudKit CKRecord-based sync when two or more users are collaborating on a document, recording only the diffs for quick updates. The app would no longer re-read the entire document when iCloud Drive updates it while in use, and would instead read the CloudKit records and apply those changes. This should be much faster.

Is my understanding of how Apple does it correct? Does my proposed approach seem sensible? Has anyone else implemented something like this, with iCloud Drive-based documents and a CloudKit live sync?

In terms of technologies, I see that Apple now has a Shared with You framework, with the ability to use a NSItemProvider to start the collaboration. Which raises the question, should I use the iCloud Drive document for the collaboration (as I do now), or the CloudKit CKShare diff? I think I'd have to use the document as a whole, both so it works with the Send Copy option, and so a user that doesn't have the document gets it when using Collaborate. Once the collaboration is underway, I'd want to start the CloudKit channel. So I guess I'd save the CKShare to the server, get its URL, and save that in the document, so another user can read that URL as part of their initial load of the document from iCloud Drive?

Once two (or more) users have the document via iCloud Drive, and the CKShare via the embedded URL, I should be able to do further live-sync updates via CloudKit. If a user closes the document and re-opens it, they'd get the updates via iCloud Drive, so no need to apply any updates from before the document was opened.

Does all this sound reasonable, or am I overlooking some gotcha? I'd appreciate any advice from people who have experience with this kind of syncing.

Answered by DTS Engineer in 821032022

I don't work for the iWork team, and so have no idea about how the synchronization of the apps is implemented, but based on your description, synchronizing the changes via CloudKit doesn't seem to address your issue.

Consider the following flow:

  1. On device A, a user makes a change.
  2. Your app saves the change to the document.
  3. Your app uploads the change to CloudKit.
  4. On device B, the user opens the document.
  5. Your app downloads the change from CloudKit, and merges it to the document.

There are two issue here:

  • At step 4, the iCloud Drive synchronization still happens, because of step 2.
  • At step 5, the CloudKit synchronization may trigger conflicts or create duplicate data.

If you choose to skip step 2 and have the data synchronize only via CloudKit, the iCloud Drive synchronization won't happen, and you can probably still present the data in the same way, but then the document data on CloudKit will be tied to the current user, and will not be available if the document is copied to the other user.

The other point may be worth mentioning is that CloudKit synchronization isn't real time either. See TN3162: Understanding CloudKit throttles for more information. This may not be an issue if you use CloudKit to synchronize small changes, but may be if the data is large and changes frequently.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

I don't work for the iWork team, and so have no idea about how the synchronization of the apps is implemented, but based on your description, synchronizing the changes via CloudKit doesn't seem to address your issue.

Consider the following flow:

  1. On device A, a user makes a change.
  2. Your app saves the change to the document.
  3. Your app uploads the change to CloudKit.
  4. On device B, the user opens the document.
  5. Your app downloads the change from CloudKit, and merges it to the document.

There are two issue here:

  • At step 4, the iCloud Drive synchronization still happens, because of step 2.
  • At step 5, the CloudKit synchronization may trigger conflicts or create duplicate data.

If you choose to skip step 2 and have the data synchronize only via CloudKit, the iCloud Drive synchronization won't happen, and you can probably still present the data in the same way, but then the document data on CloudKit will be tied to the current user, and will not be available if the document is copied to the other user.

The other point may be worth mentioning is that CloudKit synchronization isn't real time either. See TN3162: Understanding CloudKit throttles for more information. This may not be an issue if you use CloudKit to synchronize small changes, but may be if the data is large and changes frequently.

Best,
——
Ziqiao Chen
 Worldwide Developer Relations.

Collaboration of iCloud Drive document with CloudKit-based live sync
 
 
Q