2

我在这里和其他地方看到了几个线程,但似乎没有一个正在使用UserNotificationsiOS 10 的新框架

有一个在单例函数getDeliveredNotifications(completionHandler:)上调用的实例方法UNUserNotificationCentercurrent()

接收一系列传递的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)
}
4

2 回答 2

2

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

于 2019-10-05T11:45:55.563 回答
0

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

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

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

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

于 2018-09-26T11:59:14.990 回答