How to remove a remote notification from notification center using UserNotifications framework

让人想犯罪 __ 提交于 2019-12-12 21:07:17

问题


I have seen several threads on this here and elsewhere but none seem to be using the new UserNotifications framework for iOS 10

There is an instance method getDeliveredNotifications(completionHandler:) that is called on UNUserNotificationCenter singleton function current()

The completionHandler: takes an array of delivered notifications that could then be removed inside the block using removeDeliveredNotifications(withIdentifiers:)

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

My challenge is how to identify a specific notification from all delivered notifications and then remove it?

This is what I am doing right now to see if there is a remote notification delivered with the id I had sent from the server with the payload key ID. This doesn't remove the notification in question, obviously because the first function returns nil although the notification is visible in the notification center.

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

回答1:


Previosly removeDeliveredNotifications is not work properly. It seems like Apple was fixed issue because it will work for me by using the single line of code.

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

I have tried 5-6 hours in the simulator to clear local notification but no luck. When I will run code in the actual device it will like the charm.

NOTE: Please test into real device, Above method are not working in simulator.




回答2:


Note that this answer is using Swift 5 and tested on iOS 13.

We can extend UNUserNotificationCenter to remove the notification(s) of our choice. Personally, I group them by thread and remove them that way, but this extension also includes a way to remove by dictionary pair.

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

With this extension in place, you can call, for example,

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

If you also want to decrease the badge number on the app icon, you can set decreaseBadgeCount: true, or alternately call UNUserNotificationCenter.current().decreaseBadgeCount.



来源:https://stackoverflow.com/questions/42518286/how-to-remove-a-remote-notification-from-notification-center-using-usernotificat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!