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

如何用Swift在iOS 11及以上版本编程创建持久化通知?

在iOS 11+中用Swift创建持久化通知

首先明确:在iOS 11及后续版本中,我们使用UserNotifications框架(iOS 10+引入)来管理通知,所谓“持久化通知”通常指用户无法通过常规滑动操作清除、需要应用主动移除的通知。下面是完整的实现步骤:

1. 导入框架并设置代理

首先在你的AppDelegate(或iOS 13+的SceneDelegate)中导入UserNotifications,并设置通知中心的代理:

import UIKit
import UserNotifications

@main
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // 设置通知中心代理
        UNUserNotificationCenter.current().delegate = self
        // 请求通知权限
        requestNotificationPermissions()
        // 注册通知类别
        registerNotificationCategories()
        return true
    }
    
    // 其他生命周期方法...
}

2. 请求通知权限

要发送通知,首先需要向用户请求必要的权限:

private func requestNotificationPermissions() {
    let center = UNUserNotificationCenter.current()
    center.requestAuthorization(options: [.alert, .badge, .sound]) { granted, error in
        if let error = error {
            print("请求通知权限失败: \(error.localizedDescription)")
        }
        // 可根据权限授予状态做后续处理
    }
}

3. 注册持久化通知的类别

关键步骤:创建一个自定义通知类别,并设置options包含.customDismissAction——这样用户尝试清除通知时,系统会回调我们的代理方法,让我们决定是否允许清除:

private func registerNotificationCategories() {
    let center = UNUserNotificationCenter.current()
    // 创建自定义清除动作(供用户主动触发清除)
    let dismissAction = UNNotificationAction(identifier: "dismissAction",
                                             title: "清除通知",
                                             options: [])
    // 创建类别,设置.customDismissAction选项拦截默认清除行为
    let persistentCategory = UNNotificationCategory(identifier: "PersistentNotificationCategory",
                                                    actions: [dismissAction],
                                                    intentIdentifiers: [],
                                                    options: [.customDismissAction])
    // 注册类别到通知中心
    center.setNotificationCategories([persistentCategory])
}

4. 创建并发送持久化通知

构建通知内容并发送,注意要指定我们刚才注册的类别:

func sendPersistentNotification() {
    let center = UNUserNotificationCenter.current()
    
    // 构建通知内容
    let content = UNMutableNotificationContent()
    content.title = "持久化通知"
    content.body = "这条通知无法被用户手动滑动清除"
    content.sound = .default
    // 指定关联的持久化类别
    content.categoryIdentifier = "PersistentNotificationCategory"
    
    // 创建触发条件(这里用5秒后立即触发,也可设置时间/位置触发)
    let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 5, repeats: false)
    
    // 创建通知请求
    let request = UNNotificationRequest(identifier: UUID().uuidString,
                                        content: content,
                                        trigger: trigger)
    
    // 添加请求到通知中心
    center.add(request) { error in
        if let error = error {
            print("发送通知失败: \(error.localizedDescription)")
        } else {
            print("持久化通知已安排发送")
        }
    }
}

5. 拦截用户的清除操作(保持通知持久化)

实现通知中心代理方法,当用户尝试清除通知时,我们可以阻止默认行为,让通知继续留在通知中心:

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    // 拦截系统默认的清除动作
    if response.actionIdentifier == UNNotificationDismissActionIdentifier {
        // 重新发送相同内容的通知,实现持久化效果
        let content = response.notification.request.content.mutableCopy() as! UNMutableNotificationContent
        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 0.1, repeats: false)
        let newRequest = UNNotificationRequest(identifier: response.notification.request.identifier,
                                               content: content,
                                               trigger: trigger)
        center.add(newRequest)
    } else if response.actionIdentifier == "dismissAction" {
        // 用户点击自定义清除按钮,允许移除通知
        center.removeDeliveredNotifications(withIdentifiers: [response.notification.request.identifier])
    }
    // 必须调用completionHandler结束回调
    completionHandler()
}

// 可选:让通知在应用前台也能显示
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    completionHandler([.alert, .sound])
}

注意事项

  • iOS系统限制:即使做了上述设置,用户仍然可以通过“清除所有通知”来移除通知,这是系统级限制,开发者无法阻止。
  • 持久化逻辑:这种方案主要是阻止用户单独滑动清除某条通知,必须通过应用提供的动作或系统的“清除所有”来移除。
  • 测试建议:尽量在真机上测试,模拟器的通知行为可能和真机略有差异。

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:31:56