设置UNCalendarNotificationTrigger重复为true时,待处理通知请求计数不减少
问题原因与解决方案
这是因为设置了repeat = true的UNCalendarNotificationTrigger属于重复触发型通知请求,系统不会在它触发后自动从待处理队列中移除——毕竟它需要按照你设定的周期(每日/每周)重复触发。而repeat = false的是一次性通知,触发后就完成了使命,会被系统自动清理,所以待处理计数会正常减少。
针对你的场景,这里有几个可行的处理方案:
1. 手动跟踪重复通知的触发状态
不要依赖getPendingNotificationRequests的计数来判断哪些通知已经触发,而是自己维护一个存储(比如CoreData、UserDefaults或者你的业务数据库),记录每个重复通知的requestIdentifier以及它的触发情况:
- 实现
UNUserNotificationCenterDelegate的userNotificationCenter(_:didReceive:withCompletionHandler:)方法,当通知触发时,更新对应标识的触发记录。 - 当你需要统计已触发的通知数量时,直接查询自己维护的存储即可。
示例代码(触发回调中更新记录):
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let requestId = response.notification.request.identifier // 这里更新本地存储,标记该ID的通知已触发过 UserDefaults.standard.set(Date(), forKey: "triggered_\(requestId)") completionHandler() }
2. 手动清理不再需要的重复通知
如果某个重复通知已经完成使命(比如用户取消了该提醒),你可以主动调用移除方法,让它从待处理队列中消失,这样计数就会减少:
let center = UNUserNotificationCenter.current() center.removePendingNotificationRequests(withIdentifiers: ["不再需要的通知ID"])
3. 优化超64条通知的调度逻辑
因为系统限制了待处理通知的数量(通常上限64),你可以结合重复通知的触发时机来动态调度:
- 每当一条重复通知触发时,检查数据库中是否还有未调度的通知请求。
- 如果有,就从数据库取出一条,调度为新的重复通知,保持待处理队列的数量稳定在64以内。
- 注意:调度新通知前,确保不会重复添加相同ID的请求,避免冲突。
这样既符合系统限制,又能保证所有需要的重复通知都能按周期触发。
内容的提问来源于stack exchange,提问作者Vikas Rajput
相关产品推荐
相关产品推荐

