如何使用Swift按星期推送不同文案的定时本地通知
实现按星期几推送自定义本地通知的解决方案
你现有代码主要存在三个核心问题:
- 触发条件未绑定星期属性,只能固定日期/每日推送,无法实现按周几匹配内容
- 文案未读取
CustomNotification中配置的各周对应内容,使用了统一的全局文案 - 触发规则包含年月日属性,重复推送逻辑不符合周度循环的需求
第一步:补充必要依赖定义
你代码中用到的dayNumberOfWeek()方法需要先实现Date扩展,同时补全CustomNotification结构定义:
import UserNotifications // 补全Date获取周几的扩展,iOS默认1为周日,2为周一,以此类推到7为周六 extension Date { func dayNumberOfWeek() -> Int? { return Calendar.current.dateComponents([.weekday], from: self).weekday } } // 补全自定义通知结构定义 struct CustomNotification { let hours: [Int] let title: [String] let body: [String] } // 你用到的国际化枚举可按自己实际业务调整 enum Localizables { enum InformationTitles { static let notificationTitle = "日常提醒" } }
第二步:修正后的通知管理代码
public struct NotificationManager { let notificationCenter = UNUserNotificationCenter.current() static let sharedInstance = NotificationManager() private func checkRequestAuthorization(completion: @escaping(Bool) -> Void) { let options: UNAuthorizationOptions = [.alert, .sound] notificationCenter.requestAuthorization(options: options) { didAllow, error in completion(didAllow) } } // 对外调用入口,App启动时调用即可完成所有周度通知注册 func setLocalNotifications() { checkRequestAuthorization { isAllowed in guard isAllowed else { return } // 清除旧的待发送通知,避免重复 notificationCenter.removeAllPendingNotificationRequests() let weekNotificationConfigs = getNotificationsCredentials() // 遍历一周7天的配置,逐个注册通知 for (index, config) in weekNotificationConfigs.enumerated() { // 数组下标0对应周日(weekday=1),计算得到实际周几数值 let targetWeekday = index + 1 addSingleWeekdayNotification(weekday: targetWeekday, config: config) } } } // 配置各周几的推送内容和时间,可按需求自行修改 private func getNotificationsCredentials() -> [CustomNotification] { return [ CustomNotification(hours: [8,16], title: ["微笑周日", "自我周日"], body: ["今天什么事让你开心?", "今天抽点时间画画吧!"]), CustomNotification(hours: [16], title: ["正念周一"], body: ["今天试试正念练习吧!"]), CustomNotification(hours: [16], title: ["思考周二"], body: ["来玩点思维游戏吧!"]), CustomNotification(hours: [16], title: ["许愿周三"], body: ["今天是周三,你好,请完成对应事项"]), CustomNotification(hours: [16], title: ["感恩周四"], body: ["你好,今天是周四,记得完成运动任务"]), CustomNotification(hours: [16], title: ["感受周五"], body: ["今天一起来探索自己的情绪吧!"]), CustomNotification(hours: [8,16], title: ["超级周六", "歌唱周六"], body: ["今天有什么事让你超级期待?", "今天一起唱歌跳舞吧!"]) ] } // 为指定周几注册对应推送 private func addSingleWeekdayNotification(weekday: Int, config: CustomNotification) { for (hourIndex, pushHour) in config.hours.enumerated() { let content = UNMutableNotificationContent() // 读取该周几对应时间的自定义文案 content.title = config.title[hourIndex] content.body = config.body[hourIndex] content.sound = UNNotificationSound.default // 仅设置周几、小时、分钟三个属性,实现每周该时间循环触发 var triggerComponents = DateComponents() triggerComponents.timeZone = .current triggerComponents.weekday = weekday triggerComponents.hour = pushHour triggerComponents.minute = 0 // 可按需求调整分钟数 let trigger = UNCalendarNotificationTrigger(dateMatching: triggerComponents, repeats: true) // 用固定规则生成标识符,方便后续修改推送时精准查找删除 let identifier = "weekly_push_\(weekday)_\(pushHour)" let request = UNNotificationRequest(identifier: identifier, content: content, trigger: trigger) notificationCenter.add(request) { error in if let error = error { print("通知注册失败:\(error.localizedDescription)") } } } } }
注意事项
- 如果后续修改了推送文案或时间,重新调用一次
NotificationManager.sharedInstance.setLocalNotifications()即可覆盖旧的通知配置 - 需要在项目
Signing & Capabilities中添加Background Modes,勾选Remote notifications保证通知权限正常
内容的提问来源于stack exchange,提问作者berkehan Öztürk
相关产品推荐
相关产品推荐

