为什么UNCalendarNotificationTrigger设置的本地通知不触发
故障原因排查
- 未提前申请通知权限:
UNUserNotificationCenter必须先向用户申请通知展示权限,权限未通过的前提下添加的通知请求会被系统静默丢弃,不会抛出显性错误。 - 触发时间已过期:你设置的触发时间为2021年9月25日,若你运行代码的时间晚于该时间点,非重复的日历触发器不会主动触发历史时间的通知。
- 日期组件配置错误:你初始代码中通过当前日期加1天得到
nextTriggerDate,仅修改day属性为25后,年月仍为当前运行时的年月,并不会自动匹配到2021年9月,实际生成的触发时间可能和预期完全不符。 - 前台运行未配置展示规则:iOS 默认不会在App前台运行时展示通知横幅,若你仅在前台测试,会误以为通知未触发,实际通知事件已经送达。
- 日期时区偏差:未明确指定时区的前提下,
DateComponents会按照系统时区计算触发时间,可能和你预期的本地时间存在偏差。
修正方案
- 先申请通知权限,权限通过后再添加通知请求:
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in guard granted else { print("通知权限被拒绝") return } DispatchQueue.main.async { // 此处执行通知创建逻辑 let content = UNMutableNotificationContent() content.title = "Test title" content.body = "sample test body" content.subtitle = "Sub title-Date-NonRepeat" // 直接手动设置目标日期组件,避免从当前时间计算的偏差 var comps = DateComponents() comps.year = 2021 comps.month = 9 comps.day = 25 comps.hour = 12 comps.minute = 17 comps.second = 10 comps.timeZone = Calendar.current.timeZone let trigger = UNCalendarNotificationTrigger(dateMatching: comps, repeats: false) let request = UNNotificationRequest(identifier: "test.my.example", content: content, trigger: trigger) UNUserNotificationCenter.current().add(request) { error in if let err = error { print("Notification Error:\(err.localizedDescription)") } } } }
- 若需要前台也展示通知,实现
UNUserNotificationCenterDelegate代理:
// 要提前设置代理:UNUserNotificationCenter.current().delegate = self extension 你的代理类: UNUserNotificationCenterDelegate { func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification) async -> UNNotificationPresentationOptions { return [.banner, .sound] } }
- 测试时可先将触发时间设置为当前时间往后1~2分钟,确认权限和逻辑正常后再修改为目标时间。
内容的提问来源于stack exchange,提问作者Amogam
相关产品推荐
相关产品推荐

