// // TimeSpecificNotificationManager.swift // SHECommunity // // Created by Lin on 2025/7/29. // import UIKit import UserNotifications class TimeSpecificNotificationManager { static let shared = TimeSpecificNotificationManager() private init() {} // 1. 请求通知权限(必须先调用) func requestNotificationPermission() { UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in if granted { print("通知权限已允许") } else { print("通知权限被拒绝,无法发送通知") } } } // 2. 发送指定时间的本地通知(一次性) /// - Parameters: /// - title: 通知标题 /// - body: 通知内容 /// - date: 触发的具体日期时间(如 2025-08-01 09:30:00) /// - identifier: 通知唯一标识(用于后续取消等操作) func scheduleOneTimeNotification( title: String, body: String, at date: Date, identifier: String = UUID().uuidString ) { // 创建通知内容 let content = UNMutableNotificationContent() content.title = title content.body = body content.sound = .default // 通知声音 content.badge = 1 // 应用图标角标 // 将 Date 转换为 DateComponents(提取年月日时分) let components = Calendar.current.dateComponents( [.year, .month, .day, .hour, .minute], // 精确到分钟(忽略秒和毫秒) from: date ) // 创建日历触发器(一次性) let trigger = UNCalendarNotificationTrigger( dateMatching: components, repeats: false // 仅触发一次 ) // 创建通知请求 let request = UNNotificationRequest( identifier: identifier, content: content, trigger: trigger ) // 添加通知到系统 UNUserNotificationCenter.current().add(request) { error in if let error = error { print("通知添加失败:\(error.localizedDescription)") } else { print("通知已设置,将在 \(date) 触发") } } } // 3. 发送重复的指定时间通知(如每天同一时间) /// - Parameters: /// - title: 通知标题 /// - body: 通知内容 /// - hour: 小时(24小时制,如 9 表示上午9点) /// - minute: 分钟(如 30 表示30分) /// - identifier: 通知唯一标识 func scheduleRepeatingNotification( title: String, body: String, hour: Int, minute: Int, identifier: String = UUID().uuidString ) { let content = UNMutableNotificationContent() content.title = title content.body = body content.sound = .default content.badge = 1 // 设置触发时间(忽略年/月/日,仅保留时/分,配合 repeats: true 实现每天重复) var dateComponents = DateComponents() dateComponents.hour = hour // 例如:9(上午9点) dateComponents.minute = minute // 例如:30(30分) // 创建日历触发器(每天重复) let trigger = UNCalendarNotificationTrigger( dateMatching: dateComponents, repeats: true // 重复触发(根据 dateComponents 中的粒度,此处为每天) ) // 添加通知请求 let request = UNNotificationRequest( identifier: identifier, content: content, trigger: trigger ) UNUserNotificationCenter.current().add(request) { error in if let error = error { print("重复通知添加失败:\(error.localizedDescription)") } else { print("每天 \(hour):\(minute) 的重复通知已设置") } } } // 4. 取消指定标识的通知(用于取消已设置的定时通知) func cancelNotification(identifier: String) { UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: [identifier]) print("已取消标识为 \(identifier) 的通知") } }