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

如何在指定时间段后每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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 04:57:23