10.推送的扩展能力 — 打造安全的通知体验

推送的扩展能力 --- 打造安全的通知体验

1. 什么是 Notification Service Extension?

Notification Service Extension(通知服务扩展,简称 NSE)是 iOS 10 及以后系统引入的一种特殊的 App 扩展,它允许开发者在推送通知到达设备时对通知的内容进行修改和处理,从而实现丰富的推送通知效果。通过 NSE,App 可以在通知展示给用户之前,动态地修改通知的标题、内容,或者添加附件(图片、音频、视频等),增强用户体验。

简单来说,NSE 介于 APNs 推送服务器和系统通知显示之间,拦截并"加工"通知内容,使推送通知更加生动和个性化。

2. Notification Service Extension 的工作流程

  1. 推送通知到达设备 APNs 发送包含 mutable-content: 1 标记的推送通知给用户设备。
  2. 系统触发 Notification Service Extension 系统检测到通知 payload 中包含 mutable-content,自动唤醒 NSE 扩展执行。
  3. NSE 执行处理逻辑 NSE 的入口方法 didReceive(_:withContentHandler:) 被调用,开发者在这里可以修改通知内容或下载附件等。
  4. 调用 Content Handler 完成通知修改 开发者处理完后调用 contentHandler,系统将修改后的通知内容交给通知中心显示给用户。
  5. 超时处理 NSE 有约 30 秒的执行时间限制,超时系统会显示原始通知。

3. 使用场景举例

  • 添加富媒体附件:图片、GIF、音频、视频等
  • 自定义通知内容:根据业务需求,动态修改通知标题、正文
  • 内容解密:对推送加密内容进行解密后再展示
  • 下载远程资源:从网络拉取相关内容,提升通知表现力
  • 统计或日志上报:通知展示前埋点统计

1. 修改通知标题和正文

less 复制代码
 override func didReceive(_ request: UNNotificationRequest,
                          withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
    let bestContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
    bestContent?.title = "【重要提示】" + (bestContent?.title ?? "")
    bestContent?.body += "\n请及时查看。"
    contentHandler(bestContent ?? request.content)
 }

2. 动态添加本地附件资源

php 复制代码
 if let url = Bundle.main.url(forResource: "localImage", withExtension: "jpg") {
    do {
        let attachment = try UNNotificationAttachment(identifier: "image", url: url, options: nil)
        bestContent?.attachments = [attachment]
    } catch {
        print("附件添加失败: (error)")
    }
 }
 contentHandler(bestContent ?? request.content)

4. 如何配置 Notification Service Extension

  1. 新建 Target 在 Xcode 中选择 File > New > Target,选择 Notification Service Extension 模板,填写名称如 MyAppNotificationService

  2. 修改 Info.plist 默认系统会生成对应的 Info.plist,确认 NSExtension 字典配置正确。一般无需手动修改。

  3. 配置推送 Payload 需要在 APNs 推送的 payload 中添加字段:

    css 复制代码
     {
      "aps": {
        "alert": {
          "title": "标题",
          "body": "内容"
        },
        "mutable-content": 1
      },
      "customKey": "自定义数据"
     }

    mutable-content: 1 是触发 NSE 的关键。

  4. 实现处理逻辑 在 NSE 入口类 NotificationService 中重写:

    typescript 复制代码
     override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
     ​
        guard let bestAttemptContent = bestAttemptContent else {
            contentHandler(request.content)
            return
        }
     ​
        // 示例:修改标题
        bestAttemptContent.title = "(bestAttemptContent.title) [修改]"
     ​
        // 示例:下载附件(异步操作需要调用contentHandler)
        if let urlString = bestAttemptContent.userInfo["image-url"] as? String,
            let url = URL(string: urlString) {
            downloadAttachment(from: url) { attachment in
                if let attachment = attachment {
                    bestAttemptContent.attachments = [attachment]
                }
                contentHandler(bestAttemptContent)
            }
        } else {
            contentHandler(bestAttemptContent)
        }
     }
  5. 处理超时 实现:

    csharp 复制代码
     override func serviceExtensionTimeWillExpire() {
        if let contentHandler = contentHandler, let bestAttemptContent = bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
     }

    保障超时后仍能显示内容。

5. 常见问题与注意事项

  • NSE 执行时间限制 通常只有约 30 秒,超时系统自动调用 serviceExtensionTimeWillExpire(),务必保证处理逻辑高效。
  • 推送 Payload 大小限制 推送负载有限制,NSE 下载远程资源可以突破内容限制,但附件大小不能太大,通常推荐几十 MB 以内。
  • 用户权限 只有当用户允许推送通知且 App 已启用通知权限时,NSE 才会被调用。
  • 调试技巧 可以通过 Xcode 的 Scheme 设置启动 NSE 调试,或使用真机配合 Xcode 控制台调试。
  • 模拟器限制 模拟器对推送通知支持有限,尤其是扩展调试,最好在真机上调试。

6. 总结

Notification Service Extension 让开发者有能力在通知内容展示前对通知进行安全、灵活的动态处理,提升通知内容的准确性和用户体验。 它与 Notification Content Extension 搭配使用,可以共同打造出既个性化又安全的推送体系。

相关推荐
Tr2e6 小时前
🐱 从 0 到 1:用 Swift 手搓一个 macOS 桌面宠物(附源码)
macos·ios·swift
人月神话-Lee12 小时前
【WWDC】Core AI:iOS 端侧大模型新纪元
人工智能·ios·ai·swift·wwdc·core ai
2501_9160074713 小时前
iOS 开发工具选择指南 从编辑器、编译器到自动化构建
ide·vscode·ios·objective-c·个人开发·swift·敏捷流程
Fatbobman(东坡肘子)15 小时前
WWDC 2026 初印象:符合预期,但更务实 -- 肘子的 Swift 周报 #139
人工智能·macos·ios·swiftui·swift·wwdc
大熊猫侯佩1 天前
WWDC26 全网首发:SwiftUI 8 “可重排序“操作符深度解析
ios·swiftui·swift
人月神话-Lee2 天前
【图像处理】颜色空间——RGB之外的世界
图像处理·人工智能·ios·ai编程·swift·rgb·颜色空间
东坡肘子2 天前
WWDC 2026 初印象:符合预期,但更务实 -- 肘子的 Swift 周报 #139
人工智能·swiftui·swift
大熊猫侯佩2 天前
WWDC26 前瞻:苹果可能放出的“王炸”,不只是 Siri
xcode·swift·wwdc
看谷秀2 天前
swift part 6 三方库综合
swift