我如何知道 UNUserNotificationCenter 的 removeAllPendingNotificationRequests() 何时完成?

Posted

技术标签:

【中文标题】我如何知道 UNUserNotificationCenter 的 removeAllPendingNotificationRequests() 何时完成?【英文标题】:How can I know when UNUserNotificationCenter's removeAllPendingNotificationRequests() has completed? 【发布时间】:2017-07-23 18:40:34 【问题描述】:

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

我想做的是这样的:

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

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

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

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

【问题讨论】:

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

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

调用 -addNotificationRequest:将替换现有通知 具有相同标识符的请求。

也许解决方案是这样的:

    创建新的通知请求 获取所有待处理并仅过滤掉不会被替换的那些 删除不替换 添加所有新通知
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 的所有操作将在彼此之间同步。

【讨论】:

以上是关于我如何知道 UNUserNotificationCenter 的 removeAllPendingNotificationRequests() 何时完成?的主要内容,如果未能解决你的问题,请参考以下文章

Python:出现“列表索引超出范围”错误;我知道为啥但不知道如何解决

我如何知道 Jenkins 以啥用户身份运行?

如何知道我是不是在 Android 上通话?

如何知道我应该从 BLOC 或 Cubit 中选择啥

我如何知道是不是启用了 iCloud 备份?

我如何知道 AVAudioPlayer 是不是正在使用文件