Вызов registerForRemoteNotificationTypes:
и реализации didRegisterForRemoteNotificationsWithDeviceToken:
должно быть достаточно кода, а идентификатор приложения должны включать в себя Push-уведомления службы.
Я использую CloudKit в кросс-платформенной (/ OS X IOS) приложение для синхронизации избранного между устройствами таким образом:
// OS X specific code
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
[NSApp registerForRemoteNotificationTypes:NSRemoteNotificationTypeNone];// silent push notification!
}
- (void)application:(NSApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
[self.favCon handleCloudKitNotificationWithUserInfo:userInfo];
}
Обратите внимание на использование NSRemoteNotificationTypeNone
что означает молчаливое толчок уведомления! Это, как я настраивал CloudKit в классе FavController:
- (void)getOrCreateFavZoneWithCompletionHandler:(successCompletionHandler)handler {
// check if FavZone exists op
__block int createZone = 0;
CKFetchRecordZonesOperation *fetchRecZonesOp = [[CKFetchRecordZonesOperation alloc] initWithRecordZoneIDs:@[[FavController favRecordZoneID]]];
CKModifyRecordZonesOperation *saveRecZoneOp = [[CKModifyRecordZonesOperation alloc] initWithRecordZonesToSave:nil recordZoneIDsToDelete:nil];
fetchRecZonesOp.fetchRecordZonesCompletionBlock = ^(NSDictionary *recordZonesByZoneID, NSError *operationError) {
if (recordZonesByZoneID.count == 0) {// zone doesn't exist
createZone = 1;
CKRecordZone *favZone = [[CKRecordZone alloc] initWithZoneName:UTXAFavZoneName];
saveRecZoneOp.recordZonesToSave = @[favZone];
NSLog(@"Creating new Zone %@", favZone.zoneID.zoneName);
} else {
NSLog(@"Zone %@ already exists.", [FavController favRecordZoneID].zoneName);
}
};
// create FavZone op
saveRecZoneOp.modifyRecordZonesCompletionBlock = ^(NSArray *savedRecordZones, NSArray *deletedRecordZoneIDs, NSError *operationError) {
[self successCompletionHandler:(savedRecordZones.count == createZone) error:operationError informDelegate:YES handler:handler];
};
[saveRecZoneOp addDependency:fetchRecZonesOp];
[[FavController favDatabase] addOperation:fetchRecZonesOp];
[[FavController favDatabase] addOperation:saveRecZoneOp];
}
- (void)subscribeToFavChanges:(successCompletionHandler)handler {
// get current subscription
[[FavController favDatabase] fetchSubscriptionWithID:UTXAFavConCKSubscriptionID completionHandler:^(CKSubscription *subscription, NSError *error) {
if (subscription) {
NSLog(@"using existing subscription: %@", subscription);
[self successCompletionHandler:YES error:nil informDelegate:NO handler:handler];
} else {
CKSubscription *sub = [[CKSubscription alloc] initWithZoneID:[FavController favRecordZoneID]
subscriptionID:UTXAFavConCKSubscriptionID
options:0];// "You must specify 0 for this parameter. Zone subscriptions currently do not support any options."
[[FavController favDatabase] saveSubscription:sub completionHandler:^(CKSubscription *subscription, NSError *error) {
NSLog(@"created new subscription: %@ %@", subscription, error);
[self successCompletionHandler:(error == nil) error:error informDelegate:YES handler:handler];
}];
}
}];
}
Как только я добавить или удалить запись на одном устройстве, я буду получать уведомления о всех других устройствах, которые я обрабатывать как и в Класс FavController:
/// @abstract Handle push notifications sent by iCloud.
/// @discussion App delegates call this method when they receive a push notification through didReceiveRemoteNotification.
/// Currently, only airport favorites produce a PN, it is of type CKNotificationTypeRecordZone.
/// @param userInfo The userInfo dict tied to each push notification.
- (void)handleCloudKitNotificationWithUserInfo:(NSDictionary *)userInfo {
[self recursivelyCheckForPreviousCloudKitNotifications];
}
- (void)recursivelyCheckForPreviousCloudKitNotifications {
CKFetchNotificationChangesOperation *fetchOp = [[CKFetchNotificationChangesOperation alloc] initWithPreviousServerChangeToken:_defCon.notificationChangeToken];
__weak CKFetchNotificationChangesOperation *weakOp = fetchOp;
fetchOp.notificationChangedBlock = ^(CKNotification *notification) {
[self handleNotification:notification];
};
fetchOp.fetchNotificationChangesCompletionBlock = ^(CKServerChangeToken *serverChangeToken, NSError *operationError) {
NSLog(@"new notification change token: %@", serverChangeToken);
_defCon.notificationChangeToken = serverChangeToken;
if (weakOp.moreComing) {
NSLog(@"more coming!!");
[self recursivelyCheckForPreviousCloudKitNotifications];
} else {
NSLog(@"done handling notification changes.");
}
};
[[FavController favContainer] addOperation:fetchOp];
}
- (void)handleNotification:(CKNotification *)notification {// withCompletionHandler:(successCompletionHandler)handler {
if (notification.notificationType == CKNotificationTypeRecordZone) {// make sure we handle only zone changes
CKRecordZoneNotification *noti = (CKRecordZoneNotification *)notification;
if ([noti.recordZoneID.zoneName isEqualToString:[FavController favRecordZoneID].zoneName]) {
// received an update for the fav zone
[self queuedFavUpdateFromCloud];
} else {
// received an update for an unknown zone
NSLog(@"WARNING: received an update for an unknown zone: %@", noti.recordZoneID.zoneName);
}
} else {
NSLog(@"WARNING: received unknown notification: %@", notification);
}
}
У меня была такая же проблема и даже сообщалось об этом Apple в то время. В какой-то момент проблема просто исчезла. Не знаю, почему. – harryhorn
См. Мой ответ ниже – strangetimes