Как удалить удаленное уведомление из центра уведомлений с помощью платформы UserNotifications

Я видел несколько тем по этому поводу здесь и в других местах, но, похоже, ни одна из них не использует новую структуру UserNotifications для iOS 10.

Существует метод экземпляра getDeliveredNotifications(completionHandler:), который вызывается в UNUserNotificationCenter одноэлементной функции current()

completionHandler: принимает массив доставленных уведомлений, которые затем можно удалить внутри блока с помощью removeDeliveredNotifications(withIdentifiers:).

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

Моя проблема заключается в том, как определить конкретное уведомление из всех доставленных уведомлений, а затем удалить его?

Это то, что я делаю прямо сейчас, чтобы увидеть, доставлено ли удаленное уведомление с идентификатором, который я отправил с сервера с ключом полезной нагрузки 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)
}

person Ahmed Khedr    schedule 28.02.2017    source источник
comment
Любое решение для этого?   -  person karthikeyan    schedule 17.07.2018
comment
@ Ахмед Хедр, если у тебя есть решение. пожалуйста, опубликуйте здесь   -  person chimbu    schedule 20.07.2018


Ответы (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.

person CartoonChess    schedule 05.10.2019

Ранее removeDeliveredNotifications не работал должным образом. Похоже, проблема Apple была исправлена, потому что она будет работать для меня, используя одну строку кода.

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

Я пробовал 5-6 часов в симуляторе, чтобы очистить локальное уведомление, но безуспешно. Когда я буду запускать код на реальном устройстве, ему понравится очарование.

ПРИМЕЧАНИЕ. Пожалуйста, протестируйте на реальном устройстве, описанный выше метод не работает в симуляторе.

person Hitesh Surani    schedule 26.09.2018