Search code examples
iosswiftxcodecloudkit

Query Changes after receiving CKDatabaseNotification


I'm currently building an app that allows user to share events and check in their guests simultaneously using multiple phones. I managed to set up CKQuerySubscription and update, delete and create works fine but only on the primary phone (the one sharing the event).

I recently found out that for a non-primary user to get notifications, it has to get notifications from CKDatabaseNotification which i set up and it works as I am getting remote notifications when I make changes through CloudKit Dashboard.

But the notification i get (CKDatabaseNotification) does not come with anything that would allow me to find what records changed. I've tried casting it as CKNotification as suggested on this link but as expected it fails.

I have a custom zone set up and my questions are as below:

  • How do I get any information about what changed from a CKDatabaseNotification?
  • Am I even doing that the right way? I've read somewhere else as well that some people managed to set up subscription through CKQuerySubscription on a shared database as long as it is on a custom zone, which I have but my codes told me subscription failed.

Solution

  • The CKDatabaseNotification will only tell you that something has changed, not what it is. The recommended path forward is you use a CKFetchDatabaseChangesOperation to find out what record zones have changes. Then you use the record zone IDs from that operation in a CKFetchRecordZoneChangesOperation to get all the changes.

    There's a bit more information in the CloudKit Quick Start Guide

    I'm cherry picking some relevant info below:

    After app launch or the receipt of a push, your app uses CKFetchDatabaseChangesOperation and then CKFetchRecordZoneChangesOperation to ask the server for only the changes since the last time it updated.

    The key to these operations is the previousServerChangeToken object, which tells the server when your app last spoke to the server, allowing the server to return only the items that were changed since that time.

    First your app will use a CKFetchDatabaseChangesOperation to find out which zones have changed

    Then

    Next your app uses a CKFetchRecordZoneChangesOperation object with the set of zone IDs you just collected to do the following:

    • Create and update any changed records • Delete any records that no longer exist • Update the zone change tokens

    The WWDC video CloudKit Best Practices addresses this topic as well.