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

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

问题描述

所以我一直在阅读远程通知,并最终使它起作用;我们的应用程序正在从我们的服务器接收通知.如果我们的服务器满足特定条件(例如通知不再有效),我们现在想要删除或更新未读通知.我知道静默"通知是唯一的方法,但我仍然不知道该怎么做.如果无提示通知触发我的应用唤醒,我将能够安排本地通知,但我能否删除现有的远程通知?

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

此应用支持低至 iOS 9 :/

解决方案

我最终按照 TawaNicolas 在 他的回答中建议的那样去做

a>,通过使用 getDeliveredNoti.... 获取收到的通知,然后检查每个通知的 userInfo 以找到我想要删除的通知.我将可移动通知的标识符存储在一个数组中,并调用了 removeDelivered....

这正如他的回答所暗示的那样,但一开始这不起作用,我很难找出原因.我仍然不完全确定我已经修复它,但我的测试表明它正在工作 - 我的解决方案有点有意义.

问题是,在 didReceiveRemote.. 函数中,你必须在最后调用 completionHandler(.newData).这是为了通知 NotificationCenter 某些事情发生了变化.我开始怀疑这个回调是在可移除通知实际被移除之前被调用的.我检查了文档,removeDeliveredNotifications 确实是异步的.这意味着当我这样做时:

UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers:removableIDs)完成处理程序(.newData)

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

所有这些可能会也可能不会发生.正如我所经历的那样;当连接到调试器时,removeDeliveredNotifications 函数非常快,以至于它总是在调用 completionHandler 之前完成,这意味着通知在更新系统之前被删除.所以在开发这个时一切看起来都很棒.当我与调试器断开连接时,removeDeliveredNotifications 函数稍微慢了一些,而且由于它是异步的,它在我调用 completionHandler 之后完成 -导致系统更新过快.

解决此问题的最佳方法是 Apple 为我们提供 removeDeliveredNotifications 的 completionBlock,并在其中调用我们的 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),执行:关闭)}}

这里我在 didReceiveRemoteNotification:AppDelegate 中使用它:

UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers:removableIDs)RuntimeUtils.delay(秒:0.2,关闭:{完成处理程序(.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天全站免登陆