我正在开发基于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];
据我了解,标记通知读取将使其在将来的队列提取中不会显示,即使服务器更改标记重置为nil也是如此。相反,当每个fetch只有1或2个新的时,我会在每次获取中获得很多旧的通知。我可以从notificationType标志中检测到旧的,但我担心它们会出现。我在某处错过了一步吗?
答案 0 :(得分:3)
我知道这有点旧,但我遇到了同样的问题。我想我想出来了(至少在我的情况下)。
在我的代码中,我做的和你一样:也就是说,将所有的notificationID添加到数组中并在我的CKMarkNotificationsReadOperation中使用它,并且每次都返回所有通知(尽管如你所说,一种“ReadNotification”)。
我更改了我的代码,以便我只向我的数组添加“新”通知,而不是“ReadNotification”项,并发送它们。修好了。
似乎将通知发送回服务器以标记为已读,即使它已被标记为已读,也会导致它再次作为“ReadNotification”返回。
我希望这有助于某人。
答案 1 :(得分:0)
文档不是很清楚它应该说:“将通知标记为已读取会阻止后续提取操作返回”... 作为查询通知类型。进一步澄清它应该说通知将作为读取类型返回。
如果根本没有返回,那么错过推送的其他设备就不会知道有什么变化了!