如何使用 UserNotifications 框架从通知中心删除远程通知

Posted

技术标签:

【中文标题】如何使用 UserNotifications 框架从通知中心删除远程通知【英文标题】:How to remove a remote notification from notification center using UserNotifications framework 【发布时间】:2017-02-28 20:38:14 【问题描述】:

我在这里和其他地方看到了几个关于此的主题,但似乎没有一个正在使用适用于 ios 10 的新 UserNotifications 框架

有一个实例方法getDeliveredNotifications(completionHandler:)UNUserNotificationCenter单例函数current()上调用

completionHandler: 接收一组传递的通知,然后可以使用 removeDeliveredNotifications(withIdentifiers:) 在块内删除这些通知

UNUserNotificationCenter.current().getDeliveredNotifications  notifications in 
    // UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [String])

我的挑战是如何从所有已发送的通知中识别特定通知,然后将其删除?

这就是我现在正在做的事情,看看是否有一个远程通知,其中包含我从服务器发送的带有有效负载密钥ID 的 id。这不会删除有问题的通知,显然是因为第一个函数返回 nil 尽管通知在通知中心可见。

func isThereANotificationForID(_ ID: Int) -> UNNotification?     
    var foundNotification: UNNotification?

    UNUserNotificationCenter.current().getDeliveredNotifications 
        DispatchQueue.main.async 
            for notification in notifications 
                if notification.request.content.userInfo["id"] as! Int == ID 
                    foundNotification = notification
                
            
        
    

    return foundNotification


func removeNotification(_ notification: UNNotification) 
    UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [notification.request.identifier])


// Find the notification and remove it
if let deliveredNotification = isThereANotificationForID(ID) 
    removeNotification(deliveredNotification)

【问题讨论】:

有什么解决办法吗? @Ahmed Khedr 如果您有解决方案。请在这里发帖 【参考方案1】:

请注意,此答案使用 Swift 5 并在 iOS 13 上进行了测试。

我们可以扩展UNUserNotificationCenter 以删除我们选择的通知。就个人而言,我按线程对它们进行分组并以这种方式删除它们,但此扩展还包括一种按字典对删除的方法。

extension UNUserNotificationCenter 
    func decreaseBadgeCount(by notificationsRemoved: Int? = nil) 
        let notificationsRemoved = notificationsRemoved ?? 1
        DispatchQueue.main.async 
            UIApplication.shared.applicationIconBadgeNumber -= notificationsRemoved
        
    

    func removeNotifications(_ notifications: [UNNotification], decreaseBadgeCount: Bool = false) 
        let identifiers = notifications.map  $0.request.identifier 
        UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: identifiers)
        if decreaseBadgeCount 
            self.decreaseBadgeCount(by: notifications.count)
        
    

    func removeNotifications<T: Comparable>(whereKey key: AnyHashable, hasValue value: T, decreaseBadgeCount: Bool = false) 
        UNUserNotificationCenter.current().getDeliveredNotifications  notifications in
            let notificationsToRemove = notifications.filter 
                guard let userInfoValue = $0.request.content.userInfo[key] as? T else  return false 
                return userInfoValue == value
            
            self.removeNotifications(notificationsToRemove, decreaseBadgeCount: decreaseBadgeCount)
        
    

    func removeNotifications(withThreadIdentifier threadIdentifier: String, decreaseBadgeCount: Bool = false) 
        UNUserNotificationCenter.current().getDeliveredNotifications  notifications in
            let notificationsToRemove = notifications.filter  $0.request.content.threadIdentifier == threadIdentifier 
            self.removeNotifications(notificationsToRemove, decreaseBadgeCount: decreaseBadgeCount)
        
    

    func removeNotification(_ notification: UNNotification, decreaseBadgeCount: Bool = false) 
        removeNotifications([notification], decreaseBadgeCount: decreaseBadgeCount)
    

有了这个扩展,你可以调用,例如,

UNUserNotificationCenter.current().removeNotifications(whereKey: "id", hasValue: 123)

如果您还想减少应用图标上的徽章数量,可以设置decreaseBadgeCount: true,或者调用UNUserNotificationCenter.current().decreaseBadgeCount

【讨论】:

【参考方案2】:

以前removeDeliveredNotifications 无法正常工作。似乎 Apple 已解决问题,因为它可以通过使用单行代码为我工作。

UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: aryIdentifier)

我在模拟器中尝试了 5-6 个小时来清除本地通知,但没有运气。当我在实际设备中运行代码时,它会喜欢这种魅力。

注意:请在真机上测试,以上方法在模拟器中无效。

【讨论】:

以上是关于如何使用 UserNotifications 框架从通知中心删除远程通知的主要内容,如果未能解决你的问题,请参考以下文章

iOS 10 UserNotifications 框架解析

iOS 10 本地通知不起作用(迁移到 UserNotifications 框架)

如何在 iOS 10 中处理 UserNotifications 操作

Swift 2.3 中没有这样的模块“UserNotifications”

如何在特定日期前 2 天触发 UserNotifications

如何设置 UserNotifications Framework 的通知