Notification Content Extension — 是一种iOS扩展类型,它将标准的推送通知模板替换为完全自定义的用户界面。开发者可以在通知内显示图片、音频播放器、操作按钮、进度条和自定义动画,将标准横幅扩展为完整的迷你应用程序。根据WWDC 2025的数据,该扩展使用UNNotificationContentExtension,支持在一个通知中最多包含4个媒体附件,并通过UNNotificationAction处理交互操作。
要点
Notification Content Extension — 是一种应用扩展,用于覆盖iOS上的推送通知显示。可以显示一个完全在Interface Builder中设计或通过UIKit或SwiftUI编程开发的界面,而不是带有标题、消息正文和按钮的标准横幅。
与在显示前修改内容的Notification Service Extension不同,Content Extension仅负责视觉呈现。扩展在所有修改后接收准备好的通知,并决定如何显示它。这是两种通知扩展类型之间的关键区别。
当用户执行扩展手势时 — 向下滚动通知或点击通知(取决于设备型号),扩展被激活。iOS启动扩展进程,从指定的nib或storyboard创建控制器,并通过UNNotificationContentExtension传递通知。
开发从在Xcode中添加新的目标开始,使用Notification Content Extension模板。Xcode创建MainInterface.storyboard文件和一个继承自UIViewController的类,实现UNNotificationContentExtension协议。
自定义区域的最大高度 — iPhone上为320点(对于大屏型号),iPad上为352点。超出这些边界的内容将被裁剪。为适应不同尺寸,建议使用Auto Layout和UIScrollView来处理可滚动内容。宽度始终等于通知的宽度,并在设备旋转时自动更改。
Apple Human Interface Guidelines警告:通知界面应简洁,只包含一个主要元素 — 图片、播放器、地图或快速输入表单。多个交互元素会使用户过载并复杂化交互。
App Group — 扩展与主应用程序之间唯一的数据交换机制。通过App Group的共享目录可以传输缓存图片、令牌和设置。由于进程隔离,无法直接调用主应用程序的API或访问其UserDefaults。
class NotificationViewController: UIViewController {
func didReceive(
_ notification: UNNotification
) {
guard let attachment = notification
.request.content.attachments.first()
else { return }
if attachment.url.startAccessingSecurityScopedResource() {
imageView.image = UIImage(contentsOfFile:
attachment.url.path)
attachment.url.stopAccessingSecurityScopedResource()
}
}
}
UNNotificationContentExtension — 定义自定义通知生命周期的主协议。该协议提供了接收内容、处理操作和管理界面的方法。
didReceive(_:with:) 在收到通知时调用。扩展接收UNNotification对象和用于管理媒体播放器的UNNotificationContentExtensionMediaPlayPauseButtonType。在此方法中需要配置界面 — 加载图片、初始化播放器或显示数据。系统在每次实时更新通知时调用此方法。
重要的是,扩展的执行时间有限 — 大约30秒完成整个显示周期。如果界面在此时间内未准备好,iOS将显示系统通知。对于重型资源 — 从网络加载图片、解码视频 — 建议使用异步操作,并通过App Group预先缓存。
协议包含play/pause按钮的可选方法:mediaPlay、mediaPause和mediaPlayPauseButtonType。如果通知包含音频或视频内容,扩展可以显示带有系统控制元素的内置播放器。当返回相应的按钮类型时,iOS会自动在扩展的右上角添加播放按钮。
UNNotificationAttachment — 包含附加到通知的媒体数据的对象。图片、音频文件和视频在服务器上创建通知时或在Notification Service Extension中通过UNNotificationAttachment添加。
图片:JPEG、PNG、GIF、HEIF。音频:MP3、AAC、ALAC、WAV。视频:MPEG-4、H.264、HEVC。每个附件的最大大小为50 MB,每个通知最多4个附件。系统在显示通知前自动在后台下载附件,并通过security-scoped资源向扩展提供本地URL访问。
根据Apple的建议,扩展不应独立加载媒体 — UNNotificationAttachment在系统完成下载后已经包含本地URL。但是,如果附件未及时下载(例如在网络连接不良的情况下),扩展可以显示占位符或替代文本。
每个UNNotificationAttachment提供一个security-scoped URL,扩展必须通过startAccessingSecurityScopedResource()访问它,并通过stopAccessingSecurityScopedResource()释放它。这些方法必须成对调用 — 否则资源不会被释放,并会导致访问权限泄漏。
let attachment = notification.request.content.attachments.first()
guard attachment.url.startAccessingSecurityScopedResource()
else { return }
defer { attachment.url.stopAccessingSecurityScopedResource() }
let data = try Data(contentsOf: attachment.url)
imageView.image = UIImage(data: data)
Notification Content Extension支持自定义交互操作 — 显示在通知内容下方的按钮。操作在通过UNNotificationCategory创建通知类别时注册,可以是破坏性操作、文本操作或后台操作。
UNNotificationAction — 带有标题和可选破坏性标志的简单操作。UNTextInputNotificationAction — 带有文本输入字段的操作,例如用于快速回复消息。两种类型都支持UNNotificationActionOptions.authenticationRequired选项 — 在执行前需要解锁设备。
扩展通过didReceive(_:withCompletionHandler:)方法接收选中的操作,其中传递一个UNNotificationResponse对象,包含操作标识符和可选文本。扩展可以独立处理响应,或通过App Group的共享容器将其传递给主应用程序。
let category = UNNotificationCategory(
identifier: "message",
actions: [
UNTextInputNotificationAction(
identifier: "reply",
title: "Reply",
options: .authenticationRequired
),
UNNotificationAction(
identifier: "mark_read",
title: "Mark Read",
options: .foreground
)
],
intentIdentifiers: []
)
常见问题
Content Extension负责通知的可视化显示,而Service Extension负责在显示前修改内容。Content Extension在Service Extension之后工作,无法更改通知的payload。
UIKit使用Swift和Objective-C。从iOS 16开始,SwiftUI也支持通过NotificationContentView创建通知界面,带有大小和配置修饰符。
可以,从iOS 16开始,扩展可以通过UIHostingController使用SwiftUI。但是,UIKit的所有能力 — 大小、约束、security-scoped资源 — 仍然保留并应用于SwiftUI内容。
每个通知最多4个附件。每个附件最多50 MB。支持图片(JPEG、PNG、HEIF)、音频(MP3、AAC)和视频(MPEG-4、H.264)。
通过App Group — 磁盘上的共享目录。带有app group后缀的UserDefaults也可以工作。由于扩展的进程隔离,无法直接调用主应用程序的API。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。