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

如何使用UNNotificationRequest设置每月最后一天触发的本地通知

问题原因

UILocalNotification 兼容 day = 0 代表「当月最后一天」的隐含规则,但UNCalendarNotificationTrigger 要求 DateComponents 的所有属性必须为合法的日期取值,day 的合法范围是 1 到对应月份的最大天数,设置为 0 后系统无法匹配到任何有效日期,因此触发器无效,nextTriggerDate 返回 nil。

解决方法

这里提供两种兼容不同场景的实现方案:

方案1:多日期匹配+触发校验(兼容所有 iOS 10+ 版本,最稳妥)

这种方式不会漏触发,也不需要动态更新通知,适合通知内容固定的场景:

  • 注册 4 个触发器,分别匹配每月 28、29、30、31 日的 8 点
  • 在通知收到时(可以通过 UNUserNotificationCenterDelegate 的前台接收回调,或者 Notification Service Extension 处理后台/杀进程场景),判断当前日期是否为当月最后一天,是则展示通知,否则丢弃本次通知。

触发器注册示例代码:

// 替换为你自己的通知内容配置
let content = UNMutableNotificationContent()
content.title = "月度提醒"
content.body = "这是每月最后一天的通知"

let targetDays = [28, 29, 30, 31]
for day in targetDays {
    var components = DateComponents()
    components.hour = 8
    components.minute = 0
    components.day = day
    let trigger = UNCalendarNotificationTrigger(dateMatching: components, repeats: true)
    // 每个请求使用唯一ID避免覆盖
    let request = UNNotificationRequest(identifier: "monthly_last_day_\(day)", content: content, trigger: trigger)
    UNUserNotificationCenter.current().add(request)
}

最后一天校验逻辑示例:

func isLastDayOfMonth(date: Date = Date()) -> Bool {
    let calendar = Calendar.current
    guard let dayRange = calendar.range(of: .day, in: .month, for: date) else { return false }
    let currentDay = calendar.component(.day, from: date)
    return currentDay == dayRange.count
}

方案2:动态注册单触发器(适合通知内容需要每月更新的场景)

每次触发当月的最后一天通知后,计算下一个月的最后一天日期,生成对应的 DateComponents 注册新的触发器即可,这种方式只需要维护 1 个通知请求。

下一个月最后一天计算示例:

func nextMonthLastDay8AM() -> Date? {
    let calendar = Calendar.current
    // 先取当前时间之后的第一个月首日
    guard let nextMonthFirstDay = calendar.nextDate(after: Date(), matching: DateComponents(day: 1), matchingPolicy: .nextTime) else {
        return nil
    }
    // 月首日减1天即为当月最后一天
    guard let lastDay = calendar.date(byAdding: .day, value: -1, to: nextMonthFirstDay) else {
        return nil
    }
    // 拼接8点的时间
    return calendar.date(bySettingHour: 8, minute: 0, second: 0, of: lastDay)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 17:54:04