Как узнать, когда UNUserNotificationCenter removeAllPendingNotificationRequests() завершен?

В документации iOS говорится, что UNUserNotificationCenter removeAllPendingNotificationRequests() является асинхронным.

Что я хочу сделать, это:

  1. Позвоните removeAllPendingNotificationRequests(), чтобы избавиться от всех моих запланированных уведомлений

  2. Запланируйте кучу новых уведомлений, некоторые из которых могут иметь или не иметь те же идентификаторы, что и ранее

Но так как в документации сказано, что метод работает асинхронно в другом потоке (и нет параметра обратного вызова завершения), я беспокоюсь, что иногда, в зависимости от капризов потоков, времени и тому подобного, этот шаг # 1 все равно будет выполняться как Я создаю вещи на шаге 2, и поэтому они также убивают некоторые новые уведомления, которые я делаю.

Подобные вещи немного сложно проверить вручную, так как это зависит от времени. Так что мне любопытно, кто-нибудь знает, стоит ли беспокоиться об этом или нет...

Ответ 1

У меня тот же случай, что и у вас, и я знаю, что у меня нет проблем с этим кодом:

 center.getPendingNotificationRequests(completionHandler: { notifications in
            var notificationIds:[String] = []
            for notification in notifications {
                if notification.identifier != "something_taht_I_dont_dismiss"{
                    notificationIds.append(notification.identifier)
                }
            }
            self.center.removePendingNotificationRequests(withIdentifiers: notificationIds)
            createAllNewNotifications()
        })

Если вы хотите дважды проверить все, удаляются ли ожидающие уведомления, вы можете создать простой метод рекурсии для проверки.

    func removeAllNotificationsSafe() {
        center.removeAllPendingNotificationRequests()
        checkNotificationsAreRemoved()
    }

    func checkNotificationsAreRemoved() {
        center.getPendingNotificationRequests(completionHandler: { notifications in
            if notifications.count > 0 {
                self.checkNotificationsAreRemoved()
            } else {
                self.doWhathverYouWant()
            }
        }
    }

Я не верю, что это необходимо, потому что все действия UNUserNotificationCenter будут синхронизированы между собой.

Ответ 2

В документации для добавления уведомления я нашел это:

Вызов -addNotificationRequest: заменит существующее уведомление запрос с тем же идентификатором.

Возможно, решение будет примерно таким:

  1. Создавать новые запросы уведомлений
  2. Получите все ожидающие и отфильтруйте только те, которые не будут заменены
  3. Удалить не заменил
  4. Добавить все новые уведомления
let center = UNUserNotificationCenter.current()
// Create new requests
let newRequests: [UNNotificationRequest] = [...]
let identifiersForNew: [String] = newRequests.map { $0.identifier }

center.getPendingNotificationRequests { pendingRequests in
   // Get all pending notification requests and filter only the ones that will not be replaced
    let toDelete = pendingRequests.filter { !identifiersForNew.contains($0.identifier) }
    let identifiersToDelete = toDelete.map { $0.identifier }

    // Delete notifications that will not be replaced
    center.removePendingNotificationRequests(withIdentifiers: identifiersToDelete)

     // Add all new requests
     for request in newRequests {
       center.add(request, withCompletionHandler: nil)
     }
}