2014-10-29 37 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

该文档不是很清楚,应该说:“将通知标记为已读,以防止后续读取操作返回”#作为查询通知类型。进一步说明,应该说通知将作为读取类型返回。

如果它没有被返回,那么错过推送的其他设备将不知道有什么改变!