如何清除iOS的远程推送通知? [英] How to clear a remote pushed notification for iOS?

查看:487
本文介绍了如何清除iOS的远程推送通知?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

因此,我一直在阅读远程通知,并最终使它起作用.我们的应用正在接收来自服务器的通知.现在,如果服务器上满足某些条件(例如,该通知不再有效),我们希望删除或更新未读的通知.我知道静默"通知是唯一的解决方法,但是我仍然对如何处理感到困惑. 如果无提示通知触发我的应用程序唤醒,我可以安排本地通知,但可以删除已经存在的远程通知吗?

是唯一使用服务器的静默通知,并将所有通知安排为具有自定义标识符的本地通知的唯一解决方案,以后可以将其删除吗? 例如,如果我想要此功能,是否可以永远不使用从服务器到设备的fire& forget远程推送通知?

此应用程序最多支持 iOS 9 :/

解决方案

我最终做到了,就像TawaNicolas在他的答案中建议的那样. a>,通过使用getDeliveredNoti....获取收到的通知,然后检查每个通知的userInfo来查找我要删除的通知.我将可移动通知的标识符存储在数组中,并称为removeDelivered....

这正是他的答案所暗示的,但是起初并没有奏效,我很难找出原因.我仍然不能完全确定是否已修复它,但是我的测试表明它可以正常工作-我的解决方案在一定程度上是合理的.

问题是,在didReceiveRemote..函数内部,您必须最后调用completionHandler(.newData).这是为了通知NotificationCenter发生了某些更改.我开始怀疑此回调被称为 before ,可移动通知实际上已被删除.我检查了文档,并且removeDeliveredNotifications确实是异步的.这意味着当我这样做时:

UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: removableIDs)
completionHandler(.newData)

不能保证在调用第二个函数之前先完成第一个函数.这意味着completionHandler(它告诉我的NotificationCenter某些内容已更新)首先完成,然后将通知从系统中删除. (NotificationCenter显然不调用该函数之后的UI来更新其UI).

所有这可能发生.正如我所经历的;当连接到调试器时,removeDeliveredNotifications功能是如此之快,以至于它总是在调用completionHandler之前完成,这意味着在更新系统之前已删除了通知.因此,开发此工具时,一切看起来都很不错.当我断开与调试器的连接时,removeDeliveredNotifications函数会稍慢一些,并且由于它是异步的,因此在 调用completionHandler后就完成了-导致系统更新太早了.

解决此问题的最佳方法是让Apple为我们提供removeDeliveredNotifications的completeBlock并在其中调用我们的completionHandler,但是他们没有.

现在要解决此问题,我添加了0.2秒的固定延迟,对此感到不知所措.可能低于0.2,但是对于我们正在做的事情来说,这一点也不重要.

这是我创建的一个类和函数,可以轻松地从任何地方延迟某些内容:

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)
    }
}

在这里,我在AppDelegate中的didReceiveRemoteNotification:内部使用它:

UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: removableIDs)
RuntimeUtils.delay(seconds: 0.2, closure: {
    completionHandler(.newData)
})

将此延迟添加到completionHandler之后,它总是在删除通知后执行,并且无论是否连接调试器,它似乎每次都能工作.

这是一个令人作呕的问题,有一个令人讨厌的解决方法.

So I've been reading up on remote notifications, and have finally made it work; our app is receiving notifications from our server. We now want to remove or update an unread notification if a certain condition meets on our server (e.g the notification is no longer valid). I understand that "silent" notifications are the only way to go, but I am still confused as to how. If a silent notification triggers my app to wake up, I would be able to schedule local notifications, but will I be able to remove already existing remote notifications?

Is the only solution to exclusively use silent notifications from the server, and schedule all notifications as local notifications with a custom identifier which I can later remove? E.g, can I never use fire&forget remote push notifications from my server to devices if I want this feature?

Edit: This app supports down to iOS 9 :/

解决方案

I ended up doing it like TawaNicolas suggested in his answer, by getting the received notifications with getDeliveredNoti...., then check the userInfo of every notification to find which ones I wanted to delete. I stored the removable notifications' identifiers in an array, and called removeDelivered....

This is exactly as his answer suggests, but this didn't work at first, and I had a hard time finding out why. I'm still not completely sure I have fixed it, but my tests shows that it's working - and my solution somewhat makes sense.

The thing was, inside the didReceiveRemote..-function, you have to call completionHandler(.newData) at the end. This is to notify the NotificationCenter that something has changed. I started to suspect that this callback was called before the removable notifications actually got removed. I checked the documentation, and removeDeliveredNotifications is indeed async. This means that when I do this:

UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: removableIDs)
completionHandler(.newData)

it is not guaranteed that the first function is completed before calling the second function. This means that the completionHandler, which tells my NotificationCenter that something has been updated, is completed first, and THEN the notifications gets removed from the system. (NotificationCenter apparently does not invoke its own completionHandler to update the UI after that function).

All this may or may not happen. As I was experiencing; when connected to the debugger, the removeDeliveredNotifications-function was so fast that it was always completed before the completionHandler was invoked, meaning that the notifications were removed before updating the system. So everything looked great when developing this. When I disconnected from the debugger, the removeDeliveredNotifications-function was slightly slower, and since it's async, it was completed after I invoked the completionHandler - causing the system to update too soon.

The best way to solve this would be for Apple to give us a completionBlock for removeDeliveredNotifications and call our completionHandler inside it, but they haven't.

To solve this now I have gone dirty by adding a fixed delay of 0.2 seconds. It could probably be lower than 0.2, but it isn't really important with a second from or to for what we're doing.

This is a class and function I created to easily delay something from anywhere:

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)
    }
}

And here I use it inside didReceiveRemoteNotification: in AppDelegate:

UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: removableIDs)
RuntimeUtils.delay(seconds: 0.2, closure: {
    completionHandler(.newData)
})

After adding this delay to the completionHandler, it is always executed after my deletion of notification, and it seems to work every time, with or without debugger connected.

This was a disgusting problem, with a nasty fix.

这篇关于如何清除iOS的远程推送通知?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆