I'm trying to implement CloudKit subscriptions. Previously I just fetch from a custom zone using CKServerChangeToken
when my app starts and at key points in my app.
My setup purely uses a private database.
I'm just wondering if I still need to do this type of fetching if I move to using subscriptions? From the documentation I've seen it's not clear.
Rather than use a subscription query I'm using CKSubscriptionOptionsFiresOnRecordUpdate
and looping round all my record types to register for notifications.
Yes, you still need to use a CKServerChangeToken
even if you implement CKQuerySubscription
. This is how a typical (from what I've seen) CloudKit app works to keep its data in sync:
CKServerChangeToken
and fetch any new data.CKQuerySubscription
s so that your data fresh.Apple describes notifications as "best effort" which means sometimes they aren't going to arrive (and believe me, sometimes they don't). So I have found it useful to periodically fetch new changes (like every few minutes) just in case my app missed a change notification.
Here is some sample code of how to register for all changes to a Task
record type:
let subscription = CKQuerySubscription(recordType: "Task", predicate: NSPredicate(value: true), subscriptionID: "subscriptionTask", options: [.firesOnRecordCreation, .firesOnRecordUpdate, .firesOnRecordDeletion])
let info = CKNotificationInfo()
info.shouldSendContentAvailable = true
info.alertBody = "" //This needs to be set to improve notification priority
subscription.notificationInfo = info
let operation = CKModifySubscriptionsOperation(subscriptionsToSave: [subscription], subscriptionIDsToDelete: nil)
operation.modifySubscriptionsCompletionBlock = { subscriptions, subscriptionIDs, error in
//...
}
let container = CKContainer(identifier: "...")
container.privateCloudDatabase.add(operation)
I hope that helps.