【问题标题】:How can I know when UNUserNotificationCenter's removeAllPendingNotificationRequests() has completed?我如何知道 UNUserNotificationCenter 的 removeAllPendingNotificationRequests() 何时完成?
【发布时间】:2025-11-24 00:25:02
【问题描述】:

iOS 文档说UNUserNotificationCenterremoveAllPendingNotificationRequests() 是异步的。

我想做的是这样的:

  1. 致电removeAllPendingNotificationRequests() 取消我所有的预定通知

  2. 安排一堆新的通知,其中一些可能与以前的 ID 相同,也可能不同

但是由于文档说该方法在另一个线程上异步运行(并且没有完成回调参数)我担心有时,取决于线程和时间的变幻莫测等等,第 1 步仍然会当我在第 2 步中创建东西时会继续进行,因此它也会杀死我正在制作的一些新通知。

这种东西手动测试有点棘手,因为它取决于时间。所以我很好奇是否有人知道这是否是我应该担心的事情......

【问题讨论】:

  • 我也需要这个答案。不敢相信没有人提供有关它的信息。我也有同样的担心!
  • 人们希望中心本身会锁定/同步其列表,这就是add(_:withCompletionHandler:) 确实有一个完成处理程序的原因。但如果是这样的话,肯定应该记录在案。
  • 如果调用只是同步的,那么这将不是问题。

标签: ios cocoa-touch unusernotificationcenter


【解决方案1】:

在添加通知的文档中我发现了这个:

调用 -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)
     }
}

【讨论】:

  • 这里有点老话题了。但这确实帮助了我,应该是公认的答案
【解决方案2】:

我和你有同样的情况,并且知道我对这段代码没有问题:

 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 的所有操作将在彼此之间同步。

【讨论】:

    最近更新 更多