如何在指定时间段后每2秒触发重复本地通知?
实现指定延迟后每2秒重复发送通知的方案
现有代码的问题
现有代码通过循环创建多个一次性通知模拟间隔触发,存在以下不足:
- 逻辑冗余,需手动计算每个通知的触发时间
- APP重启或通知被清除后,后续通知会失效
- 无法灵活启停重复通知
解决方案
iOS系统限制UNTimeIntervalNotificationTrigger设置repeats: true时,时间间隔必须≥60秒,无法直接实现2秒间隔的系统重复通知。根据APP运行状态,分两种场景处理:
场景1:APP前台运行时
使用Timer实现精准的2秒重复触发,先延迟指定时间后启动Timer:
import UIKit import UserNotifications class ViewController: UIViewController, UNUserNotificationCenterDelegate { let notificationCenter = UNUserNotificationCenter.current() var repeatTimer: Timer? override func viewDidLoad() { super.viewDidLoad() notificationCenter.requestAuthorization(options: [.alert, .sound, .badge]) { [weak self] granted, error in guard granted, error == nil else { print("通知权限未获取") return } // 自定义初始延迟时间(示例为1分钟) let initialDelay: TimeInterval = 60 // 延迟后启动重复通知 DispatchQueue.main.asyncAfter(deadline: .now() + initialDelay) { self?.startRepeatingNotifications() } } notificationCenter.delegate = self } /// 启动每2秒重复的通知 func startRepeatingNotifications() { repeatTimer = Timer.scheduledTimer(withTimeInterval: 2, repeats: true) { [weak self] _ in self?.sendSingleNotification() } } /// 发送单条通知 func sendSingleNotification() { let content = UNMutableNotificationContent() content.title = "Alarm present" content.body = "Alarm triggered at \(Date())" content.sound = .default // 立即触发通知 let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false) let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger) notificationCenter.add(request) { error in if let error = error { print("添加通知失败:\(error.localizedDescription)") } // 可选:清除已送达的通知,避免通知中心堆积 self?.notificationCenter.removeAllDeliveredNotifications() } } /// 停止重复通知 func stopRepeatingNotifications() { repeatTimer?.invalidate() repeatTimer = nil } // 前台接收通知时,允许弹窗和播放声音 func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler([.alert, .sound]) } }
场景2:APP后台/锁屏时
后台无法使用Timer,只能通过批量创建一次性通知模拟间隔触发:
import UIKit import UserNotifications class ViewController: UIViewController, UNUserNotificationCenterDelegate { let notificationCenter = UNUserNotificationCenter.current() override func viewDidLoad() { super.viewDidLoad() notificationCenter.requestAuthorization(options: [.alert, .sound, .badge]) { [weak self] granted, error in guard granted, error == nil else { print("通知权限未获取") return } // 自定义初始延迟时间(示例为1分钟) let initialDelay: TimeInterval = 60 // 自定义重复次数(示例重复30次,总时长60秒) let repeatCount = 30 self?.scheduleBatchNotifications(initialDelay: initialDelay, repeatCount: repeatCount) } notificationCenter.delegate = self } /// 批量创建延迟通知 func scheduleBatchNotifications(initialDelay: TimeInterval, repeatCount: Int) { for index in 0...repeatCount { let triggerTime = initialDelay + TimeInterval(index * 2) let content = UNMutableNotificationContent() content.title = "Alarm present" content.body = "Alarm \(Int(triggerTime))" content.sound = .default let trigger = UNTimeIntervalNotificationTrigger(timeInterval: triggerTime, repeats: false) let request = UNNotificationRequest(identifier: "Alarm_\(index)", content: content, trigger: trigger) notificationCenter.add(request) { error in if let error = error { print("添加通知失败:\(error.localizedDescription)") } } } // 可选:清除已送达的通知 notificationCenter.removeAllDeliveredNotifications() } }
重要提示
- 系统限制:iOS原生重复通知的最小间隔为60秒,2秒间隔的需求只能通过上述两种方式模拟
- 前台Timer限制:APP进入后台后Timer会暂停,若需后台持续触发,需申请后台任务权限,但后台任务有时间限制
- 权限处理:必须先获取用户的通知授权,否则无法发送任何通知
内容的提问来源于stack exchange,提问作者Pankaj Kumawat
相关产品推荐
相关产品推荐

