In my app I use CloudKit and a user's private CKDatabase to store records. I do fetches for changes when the app starts as it adviced at WWDC 2016.
Firstly, I call the fetchDatabaseChanges(database: CKDatabase, databaseTokenKey: String, completion: @escaping () -> Void)
method.
Inside this method in changesOperation.fetchDatabaseChangesCompletionBlock
I save a CKServerChangeToken to userDefaults for a key : ckDatabaseToken
.
I also call the fetchZoneChanges(database: database, databaseTokenKey: databaseTokenKey, zoneIDs: changedZoneIDs, completion
in the changesOperation.fetchDatabaseChangesCompletionBlock
of the fetchDatabaseChanges
method.
In the fetchZoneChanges
method there is an operation.recordZoneFetchCompletionBlock
. Inside this block we also need to save the value of the token to the UserDefaults. And I'm saving it to another ckZoneToken
variable in User Defaults. So inside the fetchZoneChanges
I get and save (from/to UserDefaults) the ckZoneToken
value, and inside the fetchDatabaseChanges
, I get and save (from/to UserDefaults) the ckDatabaseToken
value .
Is it the right technique? Or it is better to use only the one variable in both fetchDatabaseChanges
and fetchZoneChanges
method sto store the value of CKServerChangeToken
?
Which will be the best approach?
Swift 3, Xcode 9
I've experimented with both ways and figured out that if we use the one changeToken in user defaults, we get a "Bad sync continuation data" error.
When I've used 2 separate values to store database changes and zone changes, I have had no errors.
So, I think that we have to cache a CKServerChangeToken both in CKDatabase and CKRecordZone separately.