推送的扩展能力 — 打造个性化的通知体验

推送的扩展能力 --- 打造个性化的通知体验

现代 App 的通知早已不仅仅是简单的文字提醒。设计良好的推送通知可以呈现丰富的视觉卡片,也能作为安全可控的消息通道,让用户在不打开 App 的情况下,获取关键信息并完成操作。

为满足这些高级需求,iOS 提供了 Notification Content Extension(通知内容扩展) ,它允许你在通知展示时,使用自定义界面替代系统默认样式,打造更丰富的视觉和交互体验。

一、什么是 Notification Content Extension?

Notification Content Extension 是 iOS 在通知展示阶段调用的一个独立模块,允许开发者:

  • 提供自定义的通知界面
  • 展示富媒体内容(图文、音视频预览)
  • 支持交互操作(按钮、文本输入等)

典型应用场景包括:

  • 新闻类 App 展示文章摘要和封面图
  • 电商类 App 展示商品卡片
  • 视频类 App 预览内容片段

二、创建通知的扩展

需要在项目中新增一个扩展模块(Target)

  • 击左下角的 + 按钮(见上图红框处),进入 "Add Target" 界面。
  • 选择 Notification Content Extension,填写名称并完成创建。

三、将扩展绑定到通知

为什么需要将通知扩展绑定到通知?

通知内容扩展是独立模块,系统不会自动知道它处理哪些通知。 只有绑定了对应的通知分类(categoryIdentifier),系统才能调用对应扩展展示和处理通知。

如果不绑定,扩展不会生效,通知只能按系统默认样式展示。

绑定步骤

为了让通知扩展正确处理通知,需要确保以下三部分的 categoryIdentifier 保持一致:

1. 通知内容中设置 categoryIdentifier
ini 复制代码
 let content = UNMutableNotificationContent()
 content.title = "每日一句"
 content.body = "你若盛开,清风自来"
 content.categoryIdentifier = "dailyQuotes"   // 分类标识
2. 创建并注册通知分类

在 App 启动时,创建一个与通知中的分类标识相同的通知分类,并注册给系统:

ini 复制代码
 let category = UNNotificationCategory(
    identifier: "dailyQuotes",  
    actions: [doneAction, inputAction],
    intentIdentifiers: [],
    options: []
 )
 ​
 // 注册分类,必须调用,否则按钮不会显示
 UNUserNotificationCenter.current().setNotificationCategories([category])

这样,系统收到带有 "categoryIdentifier": "my_custom_category" 的通知时,会自动调用绑定了该 category 的通知扩展来展示和交互。

3. 通知扩展 Info.plist 中声明支持的 category

通知扩展的 Info.plist 文件里,需要在 NSExtension → NSExtensionAttributes → UNNotificationExtensionCategory 字段填写相同的分类标识(如 "dailyQuotes"),告诉系统该扩展负责处理此类通知。

设置通知扩展的 target 最低部署版本 (Deployment Target) 不能高于你测试设备的系统版本,否则系统根本不会加载这个扩展,即便你的主 App 是可以运行的。

四、通知扩展 Info.plist 配置详解

xml 复制代码
 <key>NSExtension</key>
 <dict>
    <!-- 声明扩展类型为通知内容扩展 -->
    <key>NSExtensionPointIdentifier</key>
    <string>com.apple.usernotifications.content-extension</string>
 ​
    <!-- 通知扩展属性配置 -->
    <key>NSExtensionAttributes</key>
    <dict>
        <!-- 支持的 categoryIdentifier(与通知内容中设置的 categoryIdentifier 一致)-->
        <key>UNNotificationExtensionCategory</key>
        <array>
            <string>dailyQuotes</string>
            <string>taskReminder</string>
            <string>mediaAlert</string>
        </array>
 ​
        <!-- 展开时是否隐藏系统默认标题、正文、图片,仅显示扩展视图 -->
        <key>UNNotificationExtensionDefaultContentHidden</key>
        <true/>
 ​
        <!-- 控制初始展开高度:0.0 ~ 1.0,默认 1.0 是一半屏幕 -->
        <key>UNNotificationExtensionInitialContentSizeRatio</key>
        <real>0.7</real>
 ​
        <!-- 是否允许用户与扩展界面交互(按钮、文本输入等)-->
        <key>UNNotificationExtensionUserInteractionEnabled</key>
        <true/>
 ​
        <!-- 是否使用扩展自定义的标题,替代系统默认通知标题 -->
        <key>UNNotificationExtensionOverridesDefaultTitle</key>
        <true/>
 ​
        <!-- 如果展示音视频,是否显示播放按钮(default / none / overlay)-->
        <key>UNNotificationExtensionMediaPlayPauseButtonType</key>
        <string>overlay</string>
 ​
        <!-- 声明支持的媒体类型(如 public.audio、public.movie) -->
        <key>UNNotificationExtensionMediaFileTypes</key>
        <array>
            <string>public.audio</string>
            <string>public.movie</string>
        </array>
    </dict>
 </dict>
Key 名称 作用 类型 默认值 用途说明
UNNotificationExtensionCategory 支持的通知分类,匹配通知中的 categoryIdentifier [String]数组 必填。系统根据此字段判断哪些通知调用该扩展。
UNNotificationExtensionDefaultContentHidden 是否隐藏系统默认标题、正文及附件,完全自定义展示内容 Bool false 设置为 true 时,隐藏系统内容,仅显示自定义扩展界面。
UNNotificationExtensionInitialContentSizeRatio 通知扩展展开时的最大初始高度(相对于屏幕高度) Float 1.0 设置扩展最大展开高度比例,范围 0.0~1.0,内容不足时不会撑满。
UNNotificationExtensionUserInteractionEnabled 是否允许用户与扩展界面交互(按钮、输入框等) Bool true 控制扩展视图的交互能力。
UNNotificationExtensionOverridesDefaultTitle 是否由扩展自定义标题显示,替代系统默认标题 Bool false 设置为 true 后,默认标题不显示,需扩展自行处理标题显示。
UNNotificationExtensionMediaPlayPauseButtonType 媒体通知中播放/暂停按钮的样式 String default 仅针对音视频通知。可选值:defaultoverlaynone
UNNotificationExtensionMediaFileTypes 支持处理的媒体类型(UTType) [String]数组 声明扩展支持的媒体文件类型,系统据此判断是否使用扩展展示该通知。

五、推送内容扩展的交互

通知内容扩展中如果有按钮,默认事件无效。需要在扩展的 Info.plist 添加:

vbnet 复制代码
 <key>UNNotificationExtensionUserInteractionEnabled</key>
 <true/>
设置项 通知行为 是否可点击进入 App 是否响应扩展内按钮
未设置(默认 false 仅展示 UI ✅ 点击扩展区域可跳转 App ❌ 按钮无响应
设置为 true 支持交互(按钮、输入等) ❌ 点击扩展区域不能跳转 App ✅ 按钮可正常响应

设置为 true 后,系统认为扩展负责交互,取消点击扩展跳转 App 的行为。

跳转 App 正确做法

通过添加带 .foreground 选项的 UNNotificationAction,点击按钮可唤起 App。

调试提示:扩展内 print() 不显示

扩展运行在独立进程,默认 Xcode 只显示主 App 日志。要查看扩展日志:

  • 切换 Xcode 运行 Scheme 到通知扩展 target;
  • 运行扩展,触发交互即可在控制台看到打印或执行断点。

这样能正确调试扩展内的事件和日志。

六、不能自动展示内容扩展的原因

只在用户 主动操作通知 时触发,开发者无权干预。

原因类型 说明
安全考虑 扩展可展示敏感数据,自动展开可能泄露内容。
交互一致性 保持通知轻量,需用户主动操作保证 UI 行为统一。
系统策略限制 Content Extension 仅在用户主动操作通知时触发,开发者无法强制。

七、如何诱导用户长按展开通知?

iOS 通知扩展默认不会自动展开 ,需要用户通过长按(锁屏/通知中心)下拉(横幅) 的方式才能触发。因此,想要发挥通知扩展的价值,前提是"让用户愿意去长按"。

以下是几种实用策略,用于提升用户进行长按操作的意愿:

1. 在标题或内容中加入操作提示语

明确告诉用户"长按可查看更多"是最简单直接的引导方式,尤其在消息、日程、任务提醒等场景非常有效:

ini 复制代码
 content.title = "任务变更(长按查看详情)"
 content.body = "你有一个待办事项已延期,长按可查看最新信息。"

📌 建议位置:

  • title 末尾加括号提示(不影响主标题)
  • body 中补充可操作性说明

2. 制造信息"断点感" ------ 激发点击欲望

设计内容时可以故意留"悬念",让用户产生"点开看看"的冲动:

ini 复制代码
 content.title = "你的日程有更新..."
 content.body = "查看今日会议是否已取消?"

这种"半句未完"的表达常用于新闻推送、提醒通知、互动问候等场景,增强好奇心。

3. 利用 Emoji 和视觉符号吸引注意

在标题中巧用 Emoji、图标字符,使通知在列表中更突出:

ini 复制代码
 content.title = "📅 今日安排已更新(长按查看)"
 content.body = "上午会议时间有调整,建议查看详情。"

适当使用视觉符号能有效提升通知可见度和可点性。

4. 匹配用户时机与意图(内容精准 + 时机合适)

推送应具备强相关性和时效性,增强用户点击意愿:

  • 临近事件、限时提醒
  • 用户订阅、收藏内容相关通知
  • 明确的查看收益(优惠、奖励、反馈)

5. 利用图像预览提升吸引力

添加图片附件吸引用户长按查看大图:

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