Subscribing to Record Changes
It’s inefficient for your app to repeat a query when the results are mostly the same as the last query. Instead, subscribe to record changes, and let the server run the query in the background. The server will notify your app of changes that interest the user or app. For example, if one user of your app is interested in artwork by a certain artist, your app can be notified when new artwork by that artist is uploaded.

Save Subscriptions to the Database
In your code, create a subscription object specifying the record type, predicate, and types of changes you want to be notified about. Then save the subscription object to the database.
To create and save a subscription
Create a predicate object.
For example, subscribe to artwork from an artist (where the
artist
field in theArtwork
record type is aReference
type).CKRecordID *artistRecordID = [[CKRecordID alloc] initWithRecordName:@"Mei Chen"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"artist = %@", artistRecordID];
Create a subscription specifying the record type, predicate, and notification options.
CKSubscription *subscription = [[CKSubscription alloc]
initWithRecordType:@"Artwork"
predicate:predicate
options:CKSubscriptionOptionsFiresOnRecordCreation];
The possible values for the
options
parameter are:CKSubscriptionOptionsFiresOnRecordCreation
,CKSubscriptionOptionsFiresOnRecordDeletion
,CKSubscriptionOptionsFiresOnRecordUpdate
, andCKSubscriptionOptionsFiresOnce
. Because theoptions
parameter is a bitmask, you can subscribe to any combination of the type of changes. For example, you can passCKSubscriptionOptionsFiresOnRecordCreation | CKSubscriptionOptionsFiresOnRecordUpdate
as theoptions:
parameter to receive notification of all new data.Create a CloudKit notification object.
CKNotificationInfo *notificationInfo = [CKNotificationInfo new];
notificationInfo.alertLocalizationKey = @"New artwork by your favorite artist.";
notificationInfo.shouldBadge = YES;
To display a localized string to the user, set the notification’s
alertLocalizationKey
property (not thealertBody
property).Set the subscription’s notification object to the new CloudKit notification object.
subscription.notificationInfo = notificationInfo;
Save the subscription to the database.
CKDatabase *publicDatabase = [[CKContainer defaultContainer] publicCloudDatabase];
[publicDatabase saveSubscription:subscription
completionHandler:^(CKSubscription *subscription, NSError *error) {
if (error)
// insert error handling
}
];
In Xcode, run your app to save the subscription to the database.
Register for Push Notifications
Saving subscriptions to the database doesn’t automatically configure your app to receive notifications when a subscription fires. CloudKit uses the Apple Push Notification service (APNs) to send subscription notifications to your app, so your app needs to register for push notifications to receive them.
For iOS and tvOS apps, add this code to the application:didFinishLaunchingWithOptions:
protocol method to register for push notifications:
// Register for push notifications |
UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert categories:nil]; |
[application registerUserNotificationSettings:notificationSettings]; |
[application registerForRemoteNotifications]; |
For Mac apps, implement the applicationDidFinishLaunching:
protocol method to register for push notifications.
Optionally implement the application:didRegisterForRemoteNotificationsWithDeviceToken:
and application:didFailToRegisterForRemoteNotificationsWithError:
methods to take the appropriate action when the app successfully or unsuccessfully registers for push notifications.
Handle Push Notifications in Code
Next, implement the application:didReceiveRemoteNotification:
method to process subscription notifications when they arrive. For iOS and tvOS apps, implement the UIApplicationDelegate
protocol method and for Mac apps, implement the NSApplicationDelegate
protocol method. For example, implement this method to update views when records matching your predicate are created, updated, or deleted.
Add the
application:didReceiveRemoteNotification:
protocol method to the app’s delegate.- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
}
In the
application:didReceiveRemoteNotification:
method, convert theuserInfo
parameter to aCKNotification
object.CKNotification *cloudKitNotification = [CKNotification notificationFromRemoteNotificationDictionary:userInfo];
Get the body of the notification.
NSString *alertBody = cloudKitNotification.alertBody;
Get the new or modified record from the
CKQueryNotification
object.if (cloudKitNotification.notificationType == CKNotificationTypeQuery) {
CKRecordID *recordID = [(CKQueryNotification *)cloudKitNotification recordID];
}
Update views or notify the user according to the record changes.
Test Subscriptions
You can initially test subscriptions by running your app through Xcode and using CloudKit Dashboard to create, modify, or delete records, as described in Add, Modify, and Delete Records. Then fully test subscriptions by running your app on multiple devices. Use one device to make changes and another device to receive the subscription notifications. You use multiple devices because a notification isn’t sent to the same device that originated the notification.
For iOS and tvOS, use a device connected to your Mac (not a simulator) to test subscription notifications. Your app successfully registers for push notifications if a dialog that asks the user’s permission for your app to receive notifications.
Recap
In this chapter you learned how to:
Subscribe to record changes by using a predicate
Handle subscription notifications
Copyright © 2017 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2017-09-19