Highlight
iOS 18 引入 Broadcast Push Notifications,让服务端通过频道(Channel)向所有订阅该频道的 Live Activity 发送一次推送即可完成广播更新,无需再逐 token 发送。
核心内容
一场足球比赛,十万人同时看比分。每个人的手机上都有一个 Live Activity,每个人的 Live Activity 都有独立的 push token。服务端要做的很简单——把同一个比分更新推送给所有人。但在旧的推送模型下,这意味着逐 token 发送:存储十万个 token,循环调用 APNs 十万次,payload 完全一样。
iOS 18 引入了 Broadcast Push Notifications,解决了这个规模问题。核心概念是 Channel(频道),类似电视广播:一个频道对应一个事件,所有订阅了该频道的设备同时收到同一条推送。服务端只需要发一次请求,APNs 负责分发给所有订阅者。
整个流程分三步:第一,在 Developer Portal 开启 Broadcast Capability 后,创建频道并获取 channel ID;第二,App 端在启动 Live Activity 时通过 pushType: .channel(channelId) 订阅该频道;第三,服务端向频道发送广播推送。频道可以在 Push Notifications Console 中手动创建用于测试,生产环境则由服务端直接调用 APNs 的频道管理 API。
详细内容
开启 Broadcast Capability
在 Developer Portal 中,App 的 Capabilities 列表里 Push Notifications 下方新增了一个 Broadcast 开关。打开它,App 才能使用频道功能(00:14)。
创建频道
开发阶段使用 Push Notifications Console,进入 Channels 标签页,点击 New Channel。需要配置两项:环境和消息存储策略(01:41)。
消息存储策略有两种:
- No Storage:推送只发给当时在线的设备,不存储离线消息,但允许更高的发送配额。适合比赛比分这类高频更新场景。
- Most Recent Message:为每台离线设备存储最近一条消息,设备重连后补发。适合航班状态这类低频但关键的场景。
创建后,频道会分配一个 base64 编码的随机 channel ID。生产环境应通过服务端调用 APNs 的 Channel Management API 创建(04:58)。
订阅频道
App 端在启动 Live Activity 时指定 channel push type:
// Request a Live Activity and subscribe to broadcast push notifications
import ActivityKit
func startLiveActivity(channelId: String) {
let gameAttributes = GameAttributes()
let initialState = GameAttributes.ContentState(
home: 0, away: 0, update: "First Half"
)
try Activity.request(
attributes: gameAttributes,
content: .init(state: initialState, staleDate: nil),
pushType: .channel(channelId)
)
}
关键点:
channelId由服务端提前创建好,App 在启动 Live Activity 前从服务端获取pushType: .channel(channelId)告诉 ActivityKit 订阅该频道的广播推送,替代之前的.token方式- 调用后,ActivityKit 会自动向 APNs 注册该设备对此频道的订阅,无需手动管理 push token
- 频道的生命周期和 Live Activity 独立:即使用户关掉了 Live Activity,频道仍然存在,后续的 Live Activity 可以继续订阅
发送广播推送
测试阶段在 Push Notifications Console 中操作:选择频道 → New Notification → 填写优先级和 payload → Send。一次推送,所有订阅设备同时收到更新(07:47)。
生产环境通过新的 APNs API 发送,认证方式与现有 APNs 连接相同(证书或 token)。payload 格式与普通 Live Activity 推送一致,包含 content-state 中的更新数据和时间戳。
频道生命周期管理
频道的总数是有限制的。服务端应通过 Channel Management API 在事件结束后删除不再需要的频道。例如比赛结束后删除该比赛的频道,释放配额(10:18)。
核心启发
-
体育赛事实时比分推送:为每场比赛创建一个频道,用户点击关注时订阅该频道,比分变化时发一次广播推送即更新所有人的 Live Activity。为什么值得做:省掉了存储和管理万级 push token 的服务端成本,延迟从”逐条发送”降到”一次广播”。怎么开始:在服务端调用 Channel Management API 创建频道,App 端用
.channel(channelId)启动 Live Activity。 -
航班状态追踪:每个航班号对应一个频道,乘客订阅自己航班的频道接收登机口变更、延误、取消等通知。为什么值得做:同一航班的所有乘客状态相同,广播推送天然匹配;Most Recent Message 策略确保离线乘客重连后也能收到最新状态。怎么开始:创建频道时选择 Most Recent Message 存储策略,航班起飞或取消后删除频道。
-
多人协同任务的实时状态同步:比如外卖平台的骑手位置共享——同一订单的多人(下单者、骑手、商家)可订阅同一频道,骑手位置更新时一次广播推送同步到所有相关方。为什么值得做:相比为每个用户维护独立 push token,频道模式把 N 次推送合并为 1 次。怎么开始:下单时创建频道,App 用频道 ID 启动 Live Activity,骑手端更新位置时向频道发广播推送。
关联 Session
- Bring your Live Activity to Apple Watch — Live Activity 扩展到 Apple Watch 的 Smart Stack
- Bring your app to Siri — 通过 SiriKit 和 App Intents 将 App 功能暴露给 Siri
- Bring your app’s core features to users with App Intents — App Intents 框架的核心概念:Intents、Entities 与 Queries
- Build custom swimming workouts with WorkoutKit — 使用 WorkoutKit 创建和调度自定义游泳训练
评论
GitHub Issues · utterances