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

本地通知周期重复调度错误及自定义重复规则实现求助

修复重复通知调度问题 & 实现自定义星期重复规则

一、修复原代码中的dateComponents错误

你当前的dateComponents配置逻辑存在问题,导致重复通知无法正确触发,以下是各重复类型的正确配置逻辑:

  • .never(不重复):需精确到具体年月日时分,确保通知仅触发一次
  • .everyDay(每天重复):只保留hour和minute,这样每天到对应时间就会触发,无需限定具体日期
  • .everyWeek(每周重复):保留weekday、hour、minute,按星期几的固定时间重复,不需要day(否则会限定每月某一天,而非星期几)
  • .everyMonth(每月重复):保留day(每月的几号)、hour、minute,不需要weekday(每月固定日期重复,与星期几无关)
  • .everyYear(每年重复):保留month、day、hour、minute,不需要weekday

二、实现自定义星期重复(如周一、周二、周五)

UNCalendarNotificationTrigger不支持直接设置多个星期几的重复规则,解决方案是为每个需要重复的星期几单独创建通知请求,每个请求的trigger匹配对应星期几,重复开关设为true。
注意:Calendar.current中,周日为1,周一为2,周二为3……周六为7;需确保每个通知请求的identifier唯一,避免被覆盖。

修改后的完整代码

let addRequest = {
    let content = UNMutableNotificationContent()
    
    if !reminder.title.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty {
        content.title = reminder.title
    } else {
        content.title = "New Reminder"
    }
    
    content.subtitle = reminder.stringDate
    content.sound = UNNotificationSound.defaultRingtone
    
    let calendar = Calendar.current
    var alertOptionTime = 0.0
    
    switch alertOption {
    case .noAlerts:
        fatalError("You messed up")
    case .atTimeOfEvent:
        alertOptionTime = 0
    case .fiveMinutes:
        alertOptionTime = -300
    case .tenMinutes:
        alertOptionTime = -600
    case .fifteenMinutes:
        alertOptionTime = -900
    case .thirtyMinutes:
        alertOptionTime = -1800
    case .oneHour:
        alertOptionTime = -3600 // 原代码数值错误,修正为标准1小时间隔
    case .twoHours:
        alertOptionTime = -7200 // 原代码数值错误,修正为标准2小时间隔
    case .oneDay:
        alertOptionTime = -86400
    case .twoDay:
        alertOptionTime = -172800
    case .oneWeek:
        alertOptionTime = -604800
    }
    
    let targetDate = reminder.date.addingTimeInterval(alertOptionTime)
    
    switch reminder.repeating {
    case .never:
        let components = calendar.dateComponents([.year, .month, .day, .hour, .minute], from: targetDate)
        let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: false)
        let request = UNNotificationRequest(identifier: reminder.id.uuidString, content: content, trigger: trigger)
        self.center.add(request)
        
    case .everyDay:
        let components = calendar.dateComponents([.hour, .minute], from: targetDate)
        let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: true)
        let request = UNNotificationRequest(identifier: reminder.id.uuidString + "_daily", content: content, trigger: trigger)
        self.center.add(request)
        
    case .everyWeek:
        let components = calendar.dateComponents([.weekday, .hour, .minute], from: targetDate)
        let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: true)
        let request = UNNotificationRequest(identifier: reminder.id.uuidString + "_weekly", content: content, trigger: trigger)
        self.center.add(request)
        
    case .everyMounth: // 建议修正枚举名为everyMonth,避免拼写错误
        let components = calendar.dateComponents([.day, .hour, .minute], from: targetDate)
        let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: true)
        let request = UNNotificationRequest(identifier: reminder.id.uuidString + "_monthly", content: content, trigger: trigger)
        self.center.add(request)
        
    case .everyYear:
        let components = calendar.dateComponents([.month, .day, .hour, .minute], from: targetDate)
        let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: true)
        let request = UNNotificationRequest(identifier: reminder.id.uuidString + "_yearly", content: content, trigger: trigger)
        self.center.add(request)
        
    case .custom:
        // 自定义星期重复:示例为周一(2)、周二(3)、周五(6),可替换为用户选择的数值
        let targetWeekdays = [2, 3, 6]
        let baseComponents = calendar.dateComponents([.hour, .minute], from: targetDate)
        
        for (index, weekday) in targetWeekdays.enumerated() {
            var customComponents = baseComponents
            customComponents.weekday = weekday
            
            let trigger = UNCalendarNotificationTrigger(dateMatching: customComponents, repeats: true)
            // 为每个星期几的通知设置唯一ID,避免覆盖
            let requestId = reminder.id.uuidString + "_custom_\(index)"
            let request = UNNotificationRequest(identifier: requestId, content: content, trigger: trigger)
            self.center.add(request)
        }
    }
}

额外注意点

  1. 原代码中oneHour和twoHours的时间间隔数值错误,已修正为标准的3600秒和7200秒
  2. 枚举名everyMounth存在拼写错误,建议修正为everyMonth,降低后续维护风险
  3. 自定义重复时,务必保证每个通知请求的identifier唯一,防止旧通知被新通知覆盖

内容的提问来源于stack exchange,提问作者Nikita Kolomoec

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 07:54:58