7.2 重复推送(每日、每周等)
1. 核心方法
使用 UNCalendarNotificationTrigger 的 dateMatching 参数配置日历组件(DateComponents),结合 repeats: true 实现周期性触发。
2. 不同频率的重复推送配置
2.1 每日重复
每天固定时间触发(如上午 10:00):
var components = DateComponents()
components.hour = 10 // 小时(24 小时制)
components.minute = 0 // 分钟let trigger = UNCalendarNotificationTrigger(dateMatching: components,repeats: true
)
2.2 每周重复
每周特定星期几触发(如每周五下午 3:00):
var components = DateComponents()
components.weekday = 6 // 1=周日, 2=周一...6=周五, 7=周六
components.hour = 15
components.minute = 0let trigger = UNCalendarNotificationTrigger(dateMatching: components,repeats: true
)
2.3 每月重复
每月特定日期触发(如每月 15 日上午 9:00):
var components = DateComponents()
components.day = 15 // 每月 15 日
components.hour = 9
components.minute = 0let trigger = UNCalendarNotificationTrigger(dateMatching: components,repeats: true
)
2.4 每年重复
每年特定日期触发(如每年 12 月 25 日 8:00):
var components = DateComponents()
components.month = 12 // 12 月
components.day = 25 // 25 日
components.hour = 8
components.minute = 0let trigger = UNCalendarNotificationTrigger(dateMatching: components,repeats: true
)
2.5 自定义间隔重复
通过 UNTimeIntervalNotificationTrigger 实现固定间隔重复(如每隔 2 小时):
// 注意:repeats 为 true 时,timeInterval 必须 ≥ 60 秒
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 7200, // 2 小时 = 60*60*2 秒repeats: true
)
3. 完整代码示例(SwiftUI 中实现)
以下示例展示如何创建一个允许用户选择重复频率(每日、每周、每月)的通知功能。
import SwiftUI
import UserNotificationsstruct RepeatingNotificationView: View {// 用户选择的重复类型enum RepeatType: String, CaseIterable {case daily = "每日"case weekly = "每周"case monthly = "每月"}@State private var selectedRepeat: RepeatType = .daily@State private var notificationTime = Date()@State private var showAlert = false@State private var alertMessage = ""var body: some View {Form {// 选择重复类型Picker("重复频率", selection: $selectedRepeat) {ForEach(RepeatType.allCases, id: \.self) { type inText(type.rawValue)}}// 选择时间DatePicker("提醒时间", selection: $notificationTime, displayedComponents: .hourAndMinute)Button("保存提醒") {scheduleRepeatingNotification()}}.alert("提示", isPresented: $showAlert) {Button("确定") { }} message: {Text(alertMessage)}}// 调度重复通知private func scheduleRepeatingNotification() {let content = UNMutableNotificationContent()content.title = "\(selectedRepeat.rawValue)提醒"content.body = "这是您的\(selectedRepeat.rawValue)提醒!"content.sound = .default// 根据用户选择生成触发器let trigger: UNCalendarNotificationTrigger = {let components = Calendar.current.dateComponents([.hour, .minute, .weekday, .day],from: notificationTime)var triggerComponents = DateComponents()switch selectedRepeat {case .daily:triggerComponents.hour = components.hourtriggerComponents.minute = components.minutecase .weekly:triggerComponents.weekday = components.weekdaytriggerComponents.hour = components.hourtriggerComponents.minute = components.minutecase .monthly:triggerComponents.day = components.daytriggerComponents.hour = components.hourtriggerComponents.minute = components.minute}return UNCalendarNotificationTrigger(dateMatching: triggerComponents,repeats: true)}()// 创建并添加通知请求let identifier = "\(selectedRepeat.rawValue)_\(Date().timeIntervalSince1970)"let request = UNNotificationRequest(identifier: identifier,content: content,trigger: trigger)UNUserNotificationCenter.current().add(request) { error inDispatchQueue.main.async {if let error = error {alertMessage = "添加失败: \(error.localizedDescription)"} else {alertMessage = "\(selectedRepeat.rawValue)提醒已设置!"}showAlert = true}}}
}
4. 关键注意事项
-
标识符管理
- 使用唯一
identifier(如结合时间戳),避免重复通知被覆盖。 - 示例:
let identifier = "weekly_\(UUID().uuidString)"。
- 使用唯一
-
时区处理
- 默认使用系统时区,可通过
components.timeZone指定特定时区:triggerComponents.timeZone = TimeZone(identifier: "Asia/Shanghai")
- 默认使用系统时区,可通过
-
用户权限
- 确保已授权通知权限(
UNUserNotificationCenter.current().getNotificationSettings)。
- 确保已授权通知权限(
-
重复限制
UNTimeIntervalNotificationTrigger的重复间隔必须 ≥ 60 秒。- 日历触发器的
dateMatching必须包含足够字段(如每周重复需设置weekday)。
-
前台通知处理
- 应用在前台时默认不显示通知,需实现
UNUserNotificationCenterDelegate:func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification) async -> UNNotificationPresentationOptions {return [.banner, .sound] }
- 应用在前台时默认不显示通知,需实现
5. 应用场景示例
- 每日提醒:早晨 7 点喝水提醒。
- 每周提醒:每周五下午 5 点提交工作报告。
- 每月提醒:每月 1 日缴纳房租。
- 自定义间隔:每隔 2 小时提醒休息(需
UNTimeIntervalNotificationTrigger)。
总结
- 核心类:
UNCalendarNotificationTrigger+DateComponents实现灵活重复规则。 - 用户体验:通过 SwiftUI 表单让用户自定义频率和时间。
- 最佳实践:合理管理通知标识符,避免重复或无效通知。
通过合理设计重复通知逻辑,可以满足大部分周期性提醒需求,同时保持代码简洁和可维护性。
相关文章:
7.2 重复推送(每日、每周等)
1. 核心方法 使用 UNCalendarNotificationTrigger 的 dateMatching 参数配置日历组件(DateComponents),结合 repeats: true 实现周期性触发。 2. 不同频率的重复推送配置 2.1 每日重复 每天固定时间触发(如上午 10:00ÿ…...
【STL】list介绍(附与vector的比较)
文章目录 1.关于list2.使用2.1 list的构造2.2 list 迭代器的使用2.3 list 容量操作2.3.1 size()2.3.2 empty()2.3.3 resize() 2.4 list 元素访问2.4.1 front()2.4.2 back() 2.5 list 修改操作2.5.1 push_front()2.5.2 pop_front()2.5.3 push_back()2.5.4 pop_back()2.5.5 inser…...
Ansible:roles角色
文章目录 Roles角色Ansible Roles目录编排Roles各目录作用创建 roleplaybook调用角色调用角色方法1:调用角色方法2:调用角色方法3: roles 中 tags 使用实战案例 Roles角色 角色是ansible自1.2版本引入的新特性,用于层次性、结构化…...
找不到导入的项目“xxx\QtMsBuild\Qt.props”。请确认 Import 声明“$(QtMsBuild)\Qt.props”中计算结果为
系列文章目录 文章目录 系列文章目录前言一、问题原因 前言 新建的项目visual studio2022 使用Qt vs tools 找不到导入的项目“E:\osgEarth\DigitalSimulationPlatform\DigitalSimulationPlatform\QtMsBuild\Qt.props”。 请确认 Import 声明“$(QtMsBuild)\Qt.props”中计算结…...
Rust 是如何层层防错的
一、Rust 的多层防错机制 🧱 第一层:Rust语言自带的“编译时护盾” —— 错误连运行都跑不起来 错误类型Rust 怎么发现的?工具/机制举个例子✅ 语法缺陷写错了代码格式或语法Rust Analyzer(智能补全)少写了分号、括号…...
SQL Server 数据库邮件配置失败:SMTP 连接与权限问题
问题现象: 配置数据库邮件时,发送测试邮件失败,提示 “邮件无法发送到 SMTP 服务器,操作超时”(错误 14661)或 “服务器拒绝发件人地址”(错误 15009)。 快速诊断 检查数据库邮件配置…...
2025 年福建交安安全员考试:结合本省交通特点备考
福建地处东南沿海,交通建设具有独特特点,这对交安安全员考试备考意义重大。在桥梁建设方面,由于面临复杂的海洋环境,桥梁的防腐、防台风等安全措施成为重点。考生在学习桥梁施工安全知识时,要特别关注福建本地跨海大桥…...
OpenBMC:BmcWeb 处理http请求5 检查权限
OpenBMC:BmcWeb 处理http请求4 处理路由对象-CSDN博客 在通过url获取了路由对象后,如果该请求是有session的,那么下一步需要检查权限 1.validatePrivilege调用时传入了一个lambda(1)做为回调 validatePrivilege(req, asyncResp, rule,[req, asyncResp, &rule, params =…...
996引擎-源码学习:Cocos2d-Lua 的 class(classname, ...)
996引擎-源码学习:Cocos2d-Lua 的 class(classname, ...) 一、核心方法调用顺序用户调用入口完整调用链二、__create 工厂方法的三种情形情形1:父类为函数(自定义工厂)情形2:父类为Cocos原生类情形3:父类为普通Lua表三、方法职责与内存管理对照表四、正确使用示例示例1…...
UE5 蓝图里的声音
文章目录 支持的格式设置循环播放在场景中放置音频设置音频的衰减与不衰减在UI动画中播放声音使用蓝图节点播放声音按钮本身就可以播放声音 支持的格式 支持:WAV 不支持:MP3 设置循环播放 双击音频,打开音频设置,勾选Looping …...
「合诚」携手企企通共建新材料和健康产业采购数智化新生态
在科技革命与产业变革深度融合的时代背景下,新材料与健康产业正迎来数字化、智能化的快速发展。 技术突破与消费升级的双重驱动,推动着行业不断创新,同时也对企业的供应链管理提出了更高要求。 1、合诚:聚焦新材料与健康产业&am…...
Three.js 系列专题 7:性能优化与最佳实践
内容概述 随着 3D 场景复杂度的增加,性能优化变得至关重要。Three.js 项目可能因几何体数量、纹理大小或渲染设置而变慢。本专题将介绍减少 draw call、优化纹理和使用调试工具的最佳实践。 学习目标 学会减少 draw call 和几何体复杂度。掌握纹理压缩与内存管理。使用 Stat…...
java+postgresql+swagger-多表关联insert操作(七)
入参为json,然后根据需要对多张表进行操作: 入参格式: [{"custstoreName":"swagger-测试经销商01","customerName":"swagger-测试客户01","propertyNo":"swaggertest01",&quo…...
Git版本管理系列:(一)使用Git管理单分支
目录 基础概念介绍仓库的创建创建隐藏目录添加代码到暂存区提交代码到仓库提交记录查询比较差异标签文件删除版本回退总结 Git 是一个分布式版本控制系统(DVCS),用于跟踪文件的变更并协调多人协作开发,由 Linus Torvalds 于 2…...
mapbox基础,加载ESRI OpenStreetMap开放街景标准风格矢量图
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:mapbox 从入门到精通 文章目录 一、🍀前言1.1 ☘️mapboxgl.Map 地图对象1.1 ☘️mapboxgl.Map style属性二、🍀加载ESRI OpenStreetMap开放街景标准风…...
WGAN-GP 原理及实现(pytorch版)
WGAN-GP 原理及实现 一、WGAN-GP 原理1.1 WGAN-GP 核心原理1.2 WGAN-GP 实现步骤1.3 总结 二、WGAN-GP 实现2.1 导包2.2 数据加载和处理2.3 构建生成器2.4 构建判别器2.5 训练和保存模型2.6 图片转GIF 一、WGAN-GP 原理 Wasserstein GAN with Gradient Penalty (WGAN-GP) 是对…...
IntelliJ IDEA使用技巧(json字符串格式化)
文章目录 一、IDEA自动格式化json字符串二、配置/查找格式化快捷键 本文主要讲述idea中怎么将json字符串转换为JSON格式的内容并且有层级结构。 效果: 转换前: 转换后: 一、IDEA自动格式化json字符串 步骤一:首先创建一个临…...
synchronized锁升级详解
synchronized锁升级详解 synchronized是Java中实现线程同步的关键字,它在JVM内部实现了锁的升级机制,从偏向锁到轻量级锁再到重量级锁,这种优化是为了减少锁操作带来的性能开销。 1. 锁的四种状态 Java对象头中的Mark Word会记录锁的状态&…...
MCP基础学习一:MCP概述与基础
MCP概述与基础 什么是MCP? MCP(Model Context Protocol,模型上下文协议)是由Anthropic公司于2024年11月推出的一种开放协议,旨在实现大型语言模型(LLM)与外部数据源和工具的无缝集成。MCP通过…...
SvelteKit 最新中文文档教程(18)—— 浅层路由和 Packaging
前言 Svelte,一个语法简洁、入门容易,面向未来的前端框架。 从 Svelte 诞生之初,就备受开发者的喜爱,根据统计,从 2019 年到 2024 年,连续 6 年一直是开发者最感兴趣的前端框架 No.1: Svelte …...
集成nacos2.2.1出现的错误汇总
总结 1.jdk问题 jdk要一致 2.idea使用问题 idea启动nacos要配置,idea启动类要启动两次,并配置两次vm参数 3.项目依赖问题 依赖要正确添加,有的模块就是不能用公共模块的pom配置,需要独立配置,先后启动顺序也要注意…...
DFS 蓝桥杯
最大数字 问题描述 给定一个正整数 NN 。你可以对 NN 的任意一位数字执行任意次以下 2 种操 作: 将该位数字加 1 。如果该位数字已经是 9 , 加 1 之后变成 0 。 将该位数字减 1 。如果该位数字已经是 0 , 减 1 之后变成 9 。 你现在总共可以执行 1 号操作不超过 A…...
LabVIEW 开发如何降本增效
在 LabVIEW 开发领域,如何在确保项目质量的同时降低开发成本,是众多企业和开发者共同关注的焦点。这不仅关乎资源的高效利用,更影响项目的投资回报率和市场竞争力。下面,我们将从多个维度深入剖析降本策略,并结合具体案…...
Tomcat 负载均衡
目录 二、Tomcat Web Server 2.1 Tomcat 部署 2.1.1 Tomcat 介绍 2.1.2 Tomcat 安装 2.2 Tomcat 服务管理 2.2.1 Tomcat 启停 2.2.2 目录说明 2.2.3编辑主页 2.3 Tomcat管理控制台 2.3.1开启远程管理 2.3.2 配置远程管理密码 三、负载均衡 3.1 重新编译Nginx 3.1.1 确…...
【AI学习】AI Agent(人工智能体)
1,AI agent 1)定义 是一种能够感知环境、基于所感知到的信息进行推理和决策,并通过执行相应动作来影响环境、进而实现特定目标的智能实体。 它整合了多种人工智能技术,具备自主学习、自主行动以及与外界交互的能力,旨…...
4月8日日记
今天抖音刷到一个视频 记了一下笔记 想做自媒体,直播,抖音是最大的平台,但是我的号之前因为跟人互喷被封号了 今天想把实名认证转移到新号上,试了一下竟然这次成功了,本以为能开直播了但是 还是因为之前的号有违规记…...
【JavaScript】十六、事件捕获和事件冒泡
文章目录 1、事件流2、事件捕获3、事件捕获4、阻止冒泡5、解绑事件6、鼠标经过事件的区别7、两种事件注册语法的区别 1、事件流 先举个形象的例子:你去西安大雁塔旅游 出发找目的地时:先从你家出发,到陕西省西安市,再到雁塔区&a…...
MyBatis的第四天学习笔记下
10.MyBatis参数处理 10.1 项目信息 模块名:mybatis-007-param数据库表:t_student表结构: id: 主键name: 姓名age: 年龄height: 身高sex: 性别birth: 出生日期 sql文件: create table t_student ( id bigint auto_increm…...
基于 Spring Boot 瑞吉外卖系统开发(一)
基于 Spring Boot 瑞吉外卖系统开发(一) 系统概述 系统功能 技术选型 初始项目和数据准备 初始项目和SQL文件下载 创建数据库并导入数据 打开reggie项目 运行效果 主函数启动项目,访问URL: http://127.0.0.1:8080/backend/pag…...
Baumer工业相机堡盟工业相机如何处理偶发十万分之一或百万分之一几率出现的黑图现象(C#)
Baumer工业相机堡盟工业相机如何处理偶发十万分之一或百万分之一几率出现的黑图现象(C#) Baumer工业相机Baumer工业相机出现黑图的技术背景硬件层面软件层面环境因素 实际案例演示:BaumerVCXG-53M.I.XT 防护相机项目使用环境项目反馈问题项目…...
