iOS Swift多本地通知调度问题:隔日报药提醒触发异常求助
解决iOS用药提醒APP隔日通知无法触发的问题
问题根源
- 日期组件不完整:你的
getDateComponents()方法只提取了小时、分钟、秒和日,缺少年份和月份。UNCalendarNotificationTrigger创建一次性通知时,仅指定日会导致系统无法定位到具体某一天(会匹配每个月的对应日期),后续通知的触发器并没有指向你预期的日期。 - 循环终止逻辑错误:循环内的
guard let date = ... else {return}会在某次日期计算失败时直接终止整个函数,导致后续所有通知都无法创建,应该改为continue跳过当前错误项。 - 冗余的通知分类设置:每次调用
scheduleNotification都重复设置通知分类,虽然不影响功能,但属于不必要的重复操作,建议移到App启动时初始化一次。
修复代码
1. 修正日期组件提取方法
extension Date { public func getDateComponents() -> DateComponents { // 补充年份和月份,确保触发器能准确定位到具体某天 return Calendar.current.dateComponents([.year, .month, .day, .hour, .minute, .second], from: self) } }
2. 修正隔日通知的循环逻辑
else if notification.frequency == .alternateDay { let firstDate = notification.date for i in stride(from: 0, to: 30, by: 2) { guard let date = Calendar.current.date(byAdding: .day, value: i, to: firstDate) else { // 跳过当前错误的日期,继续创建后续通知 continue } let dateComponents = date.getDateComponents() print(date) let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: false) let request = UNNotificationRequest( identifier: notification.id + String(i), content: content, trigger: trigger) // 添加错误处理,排查单个通知创建失败的情况 UNUserNotificationCenter.current().add(request) { error in if let error = error { print("通知创建失败: \(error.localizedDescription)") } } } self.getPendingRequests() }
3. 优化通知分类初始化(可选)
将通知分类的设置移到App启动流程中,避免重复执行:
// 在AppDelegate或SceneDelegate的启动方法中添加 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // 初始化通知分类 let takenAction = UNNotificationAction(identifier: Constants.notiTakenActionIdentifier, title: Constants.notificationTakenText) let notTakenAction = UNNotificationAction(identifier: Constants.notiNotTakenActionIdentifier, title: Constants.notificationNotTakenText) let actionCategory = UNNotificationCategory(identifier: Constants.notificaitonCategoryIdentifier, actions: [takenAction, notTakenAction], intentIdentifiers: []) UNUserNotificationCenter.current().setNotificationCategories([actionCategory]) return true }
测试提示
- 修改系统日期后,需要重启App才能让通知触发器正确识别新日期(iOS系统限制)。
- 调用
UNUserNotificationCenter.current().getPendingNotificationRequests打印所有待触发通知,确认每个隔日通知的触发日期是否符合预期。
内容的提问来源于stack exchange,提问作者Venkatesh Chejarla
相关产品推荐
相关产品推荐

