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 搭配使用,可以共同打造出既个性化又安全的推送体系。

相关推荐
大熊猫侯佩1 小时前
探秘 WWDC 25 全新 #Playground 宏:提升 Swift 开发效率的超级神器
xcode·swift·wwdc
移动端小伙伴10 小时前
推送的扩展能力 — 打造个性化的通知体验
swift
移动端小伙伴10 小时前
远程推送(Remote Push Notification)
swift
移动端小伙伴10 小时前
本地通知的精准控制三角:时间、位置、情境
swift
移动端小伙伴10 小时前
本地通知内容深度解析 — 打造丰富的通知体验
swift
移动端小伙伴11 小时前
通知交互设计全解:前台显示、按钮交互与用户行为响应
swift
移动端小伙伴11 小时前
本地通知的控制中枢 — 掌控调度与生命周期管理的关键
swift
移动端小伙伴11 小时前
通知权限获取的艺术 - 如何优雅地让用户说“好”
swift
杂雾无尘11 小时前
swift 基础:关联引用讲解
ios·swift·客户端