I am creating my two CKSubscriptions
in my App Delegate's didFinishLaunchingWithOptions
method as such.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
[[UIApplication sharedApplication] registerForRemoteNotifications];
_myContainer = [CKContainer containerWithIdentifier:@"iCloud.com.isaranjha.Copyfeed"];
_privateDatabase = [_myContainer privateCloudDatabase];
[_privateDatabase fetchSubscriptionWithID:@"subscription" completionHandler:^(CKSubscription *subscription, NSError *error){
if (subscription) {
} else {
NSPredicate *predicate = [NSPredicate predicateWithValue:YES];
CKSubscription *subscription = [[CKSubscription alloc] initWithRecordType:@"Strings" predicate:predicate subscriptionID:@"subscription" options:CKSubscriptionOptionsFiresOnRecordCreation | CKSubscriptionOptionsFiresOnRecordDeletion | CKSubscriptionOptionsFiresOnRecordUpdate];
CKNotificationInfo *notificationInfo = [CKNotificationInfo new];
notificationInfo.alertBody = @"";
notificationInfo.shouldSendContentAvailable = YES;
subscription.notificationInfo = notificationInfo;
[_privateDatabase saveSubscription:subscription completionHandler:^(CKSubscription *subscription, NSError *error) {
}];
}
}];
[_privateDatabase fetchSubscriptionWithID:@"subscription1" completionHandler:^(CKSubscription *subscription, NSError *error){
if (subscription) {
} else {
NSPredicate *predicate1 = [NSPredicate predicateWithValue:YES];
CKSubscription *subscription1 = [[CKSubscription alloc] initWithRecordType:@"Images" predicate:predicate1 subscriptionID:@"subscription1" options:CKSubscriptionOptionsFiresOnRecordCreation | CKSubscriptionOptionsFiresOnRecordDeletion | CKSubscriptionOptionsFiresOnRecordUpdate];
CKNotificationInfo *notificationInfo1 = [CKNotificationInfo new];
notificationInfo1.shouldSendContentAvailable = YES;
notificationInfo1.alertBody = @"";
subscription1.notificationInfo = notificationInfo1;
[_privateDatabase saveSubscription:subscription1 completionHandler:^(CKSubscription *subscription, NSError *error) {
}];
}
}];
ViewController *view = [[ViewController alloc] init];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:view];
self.window.rootViewController = navController;
return YES;
}
Those are created successfully, as when I log out NSError
, it returns null and every time I open the app after that, it is able to fetch them correctly. However, when a record is created or deleted, on one device, say an iPhone, the notification doesn't fire (or it is not being properly received) on the other device, say a Mac. So here is how I am listening for the notifications on my Mac.
- (void)application:(NSApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(@"CKSubscription received.");
CKQueryNotification *cloudKitNotification = [CKQueryNotification notificationFromRemoteNotificationDictionary:userInfo];
[[NSNotificationCenter defaultCenter] postNotificationName:@"CloudKitUpdated" object:nil userInfo:@{@"ckNotification" : cloudKitNotification}];
}
That NSLog
unfortunately never fires.
You have an empty alertbody
With that you won't receive push notifications when your app is not active. When you manually activate your app you will be able to query for the notifications using CKFetchNotificationChangesOperation. Here is a snippet of how I use it in EVCloudKitDao:
when your app is active, then you should receive the notifications in the application didReceiveRemoteNotification.