所以我一直在阅读远程通知,并最终使其工作;我们的应用程序正在接收来自我们服我们现在想要在我们的服务器上满足特定条件时删除或更新未读通知(例如,通知不再有效)。我理解“静音”通知是唯一的方法,但我仍然对如何做到感到困惑。 如果静音通知触发我的应用程序唤醒,我将能够安排本地通知,但是我能够删除现有的远程通知吗?
唯一的解决方案是专门使用来自服务器的静默通知,并将所有通知安排为具有自定义标识符的本地通知,以后我可以删除吗? 例如,如果我想要这个功能,我是否永远不会使用火灾并忘记从我的服务器到设备的远程推送通知?
编辑:此应用支持 iOS 9 :/
答案 0 :(得分:2)
应用程序从静默通知中唤醒后,您需要使用以下方法循环接收通知:
目标-C:
[[UNUserNotificationCenter currentNotificationCenter] getDeliveredNotificationsWithCompletionHandler:^(NSArray<UNNotification *> * _Nonnull notifications) {
}];
夫特:
UNUserNotificationCenter.current().getDeliveredNotifications { (notifications: [UNNotification]) in
}
然后检查每个通知的request.content.userInfo
属性,以确定是否是您要删除的通知。
然后,您使用以下内容将其从通知中心删除:
目标-C:
[[UNUserNotificationCenter currentNotificationCenter] removeDeliveredNotificationsWithIdentifiers:@[identifier]];
夫特:
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [identifier])
其中identifier
是notification.request.identifier
属性。
编辑:如果要识别正确的通知,则必须找出您在userInfo
中可以识别正确通知的有效负载中发送的内容。 (也许是userID或eventID?这取决于你的项目。)
答案 1 :(得分:2)
我最终通过his answer中的TawaNicolas建议,通过getDeliveredNoti....
收到收到的通知,然后检查每个通知的userInfo,找到我想要删除的内容。我将可移动通知的标识符存储在一个数组中,并调用removeDelivered...
。
这正是他的回答所暗示的,但这起初并不起作用,我很难找到原因。我仍然不完全确定我已修复它,但我的测试表明它正在工作 - 我的解决方案有点合理。
事情是,在didReceiveRemote..
- 函数内,你必须在最后调用completionHandler(.newData)
。这是为了通知NotificationCenter已发生变化。我开始怀疑这个回调在之前被称为,实际上删除了可移动通知。我检查了文档,removeDeliveredNotifications
确实是异步的。这意味着当我这样做时:
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: removableIDs)
completionHandler(.newData)
无法保证在调用第二个函数之前完成第一个函数。这意味着completionHandler
首先完成告知我的NotificationCenter已更新内容的removeDeliveredNotifications
,然后从系统中删除通知。 (NotificationCenter显然不会调用自己的completionHandler来更新该函数后的UI。)
所有这些可能会或可能不会发生。正如我所经历的那样;当连接到调试器时,completionHandler
- 函数非常快,以至于在调用removeDeliveredNotifications
之前总是完成,这意味着在更新系统之前删除了通知。所以在开发它时一切看起来都很棒。当我从调试器断开连接时,completionHandler
- 函数稍慢,并且因为它是异步的,所以在我调用removeDeliveredNotifications
之后完成 - 导致系统也更新很快。
解决此问题的最佳方法是让Apple为completionHandler
提供一个completionBlock,并在其中调用class RuntimeUtils{
class func delay(seconds delay:Double, closure:@escaping ()->()){
DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + Double(Int64(delay*Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC), execute: closure)
}
}
,但他们没有。
为了解决这个问题,我现在通过添加0.2秒的固定延迟来解决这个问题。它可能低于0.2,但对于我们正在做的事情来说,它不是真的很重要。
这是我创建的一个类和函数,可以轻松地从任何地方延迟:
didReceiveRemoteNotification:
这里我在AppDelegate
中的UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: removableIDs)
RuntimeUtils.delay(seconds: 0.2, closure: {
completionHandler(.newData)
})
内使用它:
ga(function() {
console.log('Google analytics is ready');
});
将此延迟添加到completionHandler之后,它总是在我删除通知后执行,并且无论是否连接了调试器,它似乎每次都有效。
这是一个令人作呕的问题,有一个令人讨厌的修复。
答案 2 :(得分:1)
对于iOS&gt; = 10,您可以使用UNUserNotificationCenter.current().getDeliveredNotifications
和/或UNUserNotificationCenter.current().removeAllDeliveredNotifications
您还必须添加import UserNotifications
,这是一个不错的新通知框架。