As mentioned, silent push notifications work very similar to the way background fetch works. Just like background fetch, there is a special AppDelegate method that is called when a silent push notification arrives. You need to implement this method so you can handle the incoming notifications and fetch the change data from CloudKit. Add the following method to AppDelegate:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { guard let dict = userInfo as? [String: NSObject] else { completionHandler(.failed) return } cloudStore.handleNotification(dict) { result in completionHandler(result) } }
This method is called by iOS when your app receives a silent push notification from CloudKit. This message doesn't do much apart from telling CloudStore to process the notification and then it calls completionHandler to inform iOS about the result of the fetch. As you can see, this is very similar to background fetch apart from the fact that this method is called when the CloudKit server sends a push message to the app instead of when iOS decides to do so.
Lastly, add the following code at the end of application(_:didFinishLaunchingWithOptions:):
cloudStore.subscribeToChangesIfNeeded { [weak self] error in DispatchQueue.main.async { application.registerForRemoteNotifications() } if error == nil { self?.cloudStore.fetchDatabaseChanges { fetchError in if let error = fetchError { print(error) } } } }
The preceding code takes care of telling CloudStore to subscribe to changes. It also registers the app for remote notifications so CloudKit can send silent push messages to the app. Note that this type of push messaging does not require you to explicitly ask the user to send them push notifications. This type of permission is only required if you want to send the user visual push notifications. You can read more about push notifications in Chapter 22, Implementing Rich Notifications.
At this point, you can add a couple of records to your CloudKit database. Since you haven't implemented sending data to CloudKit yet, this is the best way for you to verify that your code works as expected. You should see the names of the movies and family members you have added in the CloudKit dashboard printed to the console. Once you have the app running, try adding a new family member while the app is open. You should see the name of the new family member appear in the console right after you add the record to the CloudKit dashboard. Pretty neat, right?