There's nothing of interest in the code, but I did confirm that the operation was indeed enqueued to the private database, though, as you say, it should have been enqueued to the shared database. So, my error!
Post
Replies
Boosts
Views
Activity
More info. A follow-on error reports that "PrivateDB can't be used to access another user's zone" so I'm guessing that subscriber B is attempting to save to owner A's private database instead of subscriber B's shared database.
Still investigating...
I just encountered this myself. Did you find a solution?
How I encountered it: A creates a ToDo list and shares it with B, which works fine. Both A (owner) and B (subscriber) see the list.
A adds ItemOne to the list, which works fine. Both A and B can now see that the list contains a single item, ItemOne.
B adds ItemTwo to the list, which causes the error you've noted.
In my example, ItemTwo.parent is properly set to the shared list. Seems like it should work, and DOES work when owner A tries it, but not when subscriber B tries it.
Still investigating...
I have seen CloudKit deliver 1K of data in under 1 second, but I've also seen it take more 10 seconds or more to deliver the same 1K of data. As far as I know it makes no performance guarantees.(I've used CloudKit many times to move small bits of data between devices, but never for time-critical use. It's certainly quick enough—by the time I've made a change on Device A and look over to Device B, the update's often already complete—but depending on your requirements the occasionally higher latency might make it unsuitable.)
I use these with success:Getlet tokenData = // stored locallylet token = try NSKeyedUnarchiver.unarchivedObject(ofClass: CKServerChangeToken.self, from: tokenData)Setlet token: CKServerChangeToken? = the token from CK to be stored locallylet tokenData = try NSKeyedArchiver.archivedData(withRootObject: token, requiringSecureCoding: false)// store tokenData locally
One simple approach is to first query for the existence of the record. If you receive a successful response of null, then write the record. This leaves open a possibility of a race condition if two devices are both doing this simultaneously, but in that case you can always use the earliest of the returned records.A second and equally simple approach would be to write the record in all cases, but only query for the record with the earliest creationDate, permitting the first written record to be used by all devices.