问题
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