2015-08-20 6 views
2

Я использую следующий CKNotification информацию, и это, кажется, работает нормально:CloudKit didReceiveRemoteNotification не называется на Mac

CKNotificationInfo *note = [[CKNotificationInfo alloc] init]; note.alertBody = @"Something Happened"; note.shouldBadge = NO; note.shouldSendContentAvailable = NO;

Когда что-то меняется на устройстве IOS, мой Mac приложение получает уведомление принудительного, основываясь на подписку с этим уведомлением. Однако didReceiveRemoteNotification никогда не вызывается, поэтому я не могу обработать событие. Мне нужно обновить и получить новые изменения. Как мне это сделать?

+0

У меня была такая же проблема и даже сообщалось об этом Apple в то время. В какой-то момент проблема просто исчезла. Не знаю, почему. – harryhorn

+0

См. Мой ответ ниже – strangetimes

ответ

0

Хорошо, я, наконец, понял это. Если вы используете CKNotificationInfo для своих предупреждений, didReceiveRemoteNotification НЕ будет вызываться на Mac до тех пор, пока вы не установите CKNotificationInfo.soundName в пустую строку! Это похоже на ошибку только в OS X (10.10 & 10.11 до сих пор), но ее можно обойти с помощью этого простого изменения.

+0

Да, я читал это раньше. Обратите внимание, что мой примерный код предназначен для бесшумных push-уведомлений. Я отредактирую публикацию соответственно. – Mojo66

+0

Конечно, но в моем конкретном вопросе я использую «CKNotificationInfo». Кстати, я тоже использую тихие уведомления, просто предоставив информацию о уведомлении пустым заголовком. – strangetimes

+0

Я пробовал это, и это не сработало для меня. –

4

Вызов 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); 
    } 
} 
+0

Нет. Как я уже говорил, я говорю о CloudKit и автоматических уведомлениях о подписке на подписку. По-видимому, это известная ошибка. – strangetimes

+0

У вас есть ссылка на эту ошибку? – Mojo66

+0

Я сообщил об этом Apple. Это хорошо протестированная и воспроизводимая ошибка с CloudKit на OS X, все версии. – strangetimes