2014-10-29 22 views
4

我正在研究基於CloudKit的應用程序,該應用程序使用CKSubscription通知來跟蹤對公共數據庫的更改。每當應用程序接收推送通知我檢查通知隊列CKFetchNotificationChangesOperation和標記處理之後讀取每個通知:CKFetchNotificationChangesOperation返回舊通知

__block NSMutableArray *notificationIds = [NSMutableArray new]; 

CKFetchNotificationChangesOperation *operation = [[CKFetchNotificationChangesOperation alloc] initWithPreviousServerChangeToken:self.serverChangeToken]; 
operation.notificationChangedBlock = ^(CKNotification *notification) { 
    [notificationIds addObject:notification.notificationID]; 
    [self processRemoteNotification:notification withCompletionHandler:completionHandler]; 
}; 

__weak CKFetchNotificationChangesOperation *operationLocal = operation; 
operation.fetchNotificationChangesCompletionBlock = ^(CKServerChangeToken *serverChangeToken, NSError *operationError) { 
    if (operationError) { 
     NSLog(@"Unable to fetch queued notifications: %@", operationError); 
    } 
    else { 
     self.serverChangeToken = serverChangeToken; 
     completionHandler(UIBackgroundFetchResultNewData); 

     // Mark the processed notifications as read so they're not delivered again if the token gets reset. 
     CKMarkNotificationsReadOperation *markReadOperation = [[CKMarkNotificationsReadOperation alloc] initWithNotificationIDsToMarkRead:[notificationIds copy]]; 
     [notificationIds removeAllObjects]; 

     markReadOperation.markNotificationsReadCompletionBlock = ^(NSArray *notificationIDsMarkedRead, NSError *operationError) { 
      if (operationError) { 
       NSLog(@"Unable to mark notifications read: %@", operationError); 
      } 
      else { 
       NSLog(@"%lu notifications marked read.", (unsigned long)[notificationIDsMarkedRead count]); 
      } 
     }; 

     [[CKContainer defaultContainer] addOperation:markReadOperation]; 

     if (operationLocal.moreComing) { 
      NSLog(@"Fetching more"); 
      [self checkNotificationQueueWithCompletionHandler:completionHandler]; 
     } 
    } 
}; 

[[CKContainer defaultContainer] addOperation:operation]; 

據我所知,標誌着通知讀操作將保持它顯示了在未來的隊列中取出,甚至如果服務器更改令牌重置爲零。相反,如果應該只有1個或2個新的更改標記,則每次獲取時都會收到很多舊通知。我可以從notificationType標誌中檢測到舊的,但是我擔心它們會顯示出來。我在某個地方錯過了一步嗎?

+0

我有這個相同的問題。 http://stackoverflow.com/questions/27007014/ios-8-cloudkit-cknotifications-keep-showing-up-marked-as-cknotificationtyperea – 2014-11-19 19:16:31

+0

@GregMaletic你仍然有這個問題? – user2924482 2015-05-26 09:26:28

+0

@ user2924482我不是。爲什麼它現在正在工作,而不是之前,我不確定! – 2015-05-28 17:36:38

回答

3

我知道這有點舊,但我遇到了同樣的問題。我想我已經弄明白了(至少對我來說)。

在我的代碼中,我和你一樣:即將所有的notificationIDs添加到數組中,並在CKMarkNotificationsReadOperation中使用它,並且還獲取了每次返回的所有通知(儘管如您所述,使用一種「ReadNotification」)。

我改變了我的代碼,以便我只向我的數組中添加「新」通知,而不是「ReadNotification」項併發送這些通知。這解決了它。

似乎將通知發送回服務器以標記爲已讀,即使它已被標記爲已讀,也會導致它再次作爲「ReadNotification」返回。

我希望這可以幫助別人。

+0

有趣。我的項目暫時停滯不前。當它變成活躍的agin時,我一定會嘗試你的解決方案。 – 2015-10-02 12:50:29

+0

謝謝,文檔使得它聽起來像讀取通知再也不會通過獲取通知來返回。 – malhal 2016-02-10 23:00:45

0

該文檔不是很清楚,應該說:「將通知標記爲已讀,以防止後續讀取操作返回」#作爲查詢通知類型。進一步說明,應該說通知將作爲讀取類型返回。

如果它沒有被返回,那麼錯過推送的其他設備將不知道有什麼改變!