You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在指定起始日期后重复发送iOS本地通知?

问题解答

核心疑问解答

如果给dateComponents同时设置年、月、日、时、分参数,且repeats=true,系统只会触发一次通知。原因是:

  • UNCalendarNotificationTrigger的重复逻辑依赖「周期性时间模式」,比如每日、每周、每年重复。
  • 当你指定固定的年、月、日时,这个时间点是唯一的,后续日期无法匹配所有参数(比如下一年的年份和指定年份不一致),因此触发器只会在指定的年月日时分触发一次,不会重复。

实现「从指定起始日期开始每日重复通知」的正确方案

你的需求是让通知从指定起始日期的时分开始,之后每日同一时间触发,不能提前触发。直接用带年月日的重复触发器无法实现,推荐分两步处理:

方案逻辑

  1. 第一次通知:创建一个非重复的触发器,精准匹配起始日期的年、月、日、时、分,确保第一次通知在指定日期触发。
  2. 后续重复通知:在起始日期之后,创建一个仅包含时、分参数的重复触发器,实现每日同一时间通知。

代码实现

func addDailyNotificationStartingFrom(text: String, startDate: Date, id: String) {
    let currentDate = Date()
    let content = UNMutableNotificationContent()
    
    // 配置通知内容
    content.title = "My App"
    content.body = text
    content.sound = .default
    content.badge = NSNumber(integerLiteral: UIApplication.shared.applicationIconBadgeNumber + 1)
    
    if startDate > currentDate {
        // 1. 添加起始日期的单次通知
        let firstDateComponents = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: startDate)
        let firstTrigger = UNCalendarNotificationTrigger(dateMatching: firstDateComponents, repeats: false)
        let firstRequest = UNNotificationRequest(identifier: "\(id)_first", content: content, trigger: firstTrigger)
        
        UNUserNotificationCenter.current().add(firstRequest) { error in
            if let error = error {
                print(error.localizedDescription)
            }
        }
        
        // 2. 添加从起始日期次日开始的每日重复通知
        guard let nextDayDate = Calendar.current.date(byAdding: .day, value: 1, to: startDate) else { return }
        let repeatDateComponents = Calendar.current.dateComponents([.hour, .minute], from: nextDayDate)
        let repeatTrigger = UNCalendarNotificationTrigger(dateMatching: repeatDateComponents, repeats: true)
        let repeatRequest = UNNotificationRequest(identifier: id, content: content, trigger: repeatTrigger)
        
        UNUserNotificationCenter.current().add(repeatRequest) { error in
            if let error = error {
                print(error.localizedDescription)
            }
        }
    } else {
        // 起始日期已过,直接添加每日重复通知(下一次触发为次日的指定时分)
        let repeatDateComponents = Calendar.current.dateComponents([.hour, .minute], from: startDate)
        let repeatTrigger = UNCalendarNotificationTrigger(dateMatching: repeatDateComponents, repeats: true)
        let repeatRequest = UNNotificationRequest(identifier: id, content: content, trigger: repeatTrigger)
        
        UNUserNotificationCenter.current().add(repeatRequest) { error in
            if let error = error {
                print(error.localizedDescription)
            }
        }
    }
}

代码说明

  • 先判断起始日期是否在当前时间之后:
    • 若起始日期在未来:先触发一次指定日期的通知,再从次日开始每日重复。
    • 若起始日期已过:直接启动每日重复通知,下一次触发为次日的指定时分。
  • 用不同的identifier区分单次通知和重复通知,方便后续管理(比如取消通知)。

内容的提问来源于stack exchange,提问作者Hugo Silva

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 10:26:04