CKFetchNotificationChangesOperation返回旧的通知

我正在使用一个基于CloudKit的应用程序,它使用CKSubscription通知来跟踪对公共数据库的更改。 每当应用程序收到一个推送通知,我检查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标志中检测到旧的,但是我担心他们显示出来了。 我在某个地方错过了一个步骤吗?

我知道这有点旧了,但是我遇到了同样的问题。 我想我知道了(至less在我的情况下)。

在我的代码中,我和你一样:就是将所有的notificationIDs添加到一个数组中,并在CKMarkNotificationsReadOperation中使用它,并且每次都返回所有的通知(尽pipe如你所述, “ReadNotification”)。

我改变了我的代码,以便我只是添加“新”通知到我的数组,而不是“ReadNotification”项目,并发送这些。 这固定它。

看起来,发送一个通知回到服务器被标记为已读,即使它已经被标记为这样,将导致它被再次作为“ReadNotification”返回。

我希望这可以帮助别人。

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

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