如何使用UserNotifications框架

时间:2017-02-28 20:38:15

标签: usernotifications

我已经在这里和其他地方看到了几个线程,但似乎没有人使用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)
}

2 个答案:

答案 0 :(得分:0)

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

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

我在模拟器中尝试了5-6个小时来清除本地通知,但没有运气。当我在实际设备中运行代码时,它会很吸引人。

注意:请在真实设备中进行测试,以上方法在模拟器中不起作用。

答案 1 :(得分:0)

请注意,此答案使用的是 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