iOS 实时活动
Live Activities (实时活动) 会在 iPhone 或 iPad 的锁定屏幕和动态岛上显示您应用的最新数据。此功能允许用户一目了然地查看实时信息,并执行与显示信息相关的快速操作。
以下是使用 Live Activities 的几个示例:
- 在配送应用中显示订单状态;
- 在训练应用中提供实时倒计时;
- 在出租车应用中显示跟踪信息;
- 在体育应用中显示比赛统计数据和当前比分;
- 在天气应用中提供每小时预报。
您可以使用 Pushwoosh iOS SDK 启用 Live Activities,如下所述。要管理 Live Activities 并更新其内容,请使用 /updateLiveActivity 方法。
添加小组件扩展
Anchor link to- 创建一个新目标
前往 File > New > Target 并选择 Widget Extension。

- 小组件扩展配置 请输入名称,并确保选择 Include Live Activity,然后点击 Finish。

Info.plist 配置
Anchor link to在主目标中找到 Info.plist 文件,插入 “Supports Live Activities” 键,并将其值设置为 YES。
<key>NSSupportsLiveActivities</key> <true/>从应用启用实时活动
Anchor link to要启用 Live Activities,请将其代码添加到您现有的小组件扩展中,或者如果您的应用还没有,则创建一个新的。Live Activities 使用 SwiftUI 和 WidgetKit 功能来实现其用户界面。ActivityKit 处理每个 Live Activity 的生命周期:其 API 用于请求、更新和结束 Live Activity,并接收 ActivityKit 推送通知。您可以在 Apple 文档中了解有关 Live Activities 的更多信息。
- 在 Xcode 中导航到项目的 ContentView 文件并创建一个 Button
import SwiftUI
struct ContentView: View { var body: some View { VStack(spacing: 20) {
Button(action: { LiveActivityManager.shared.startActivity() }, label: { Text("Start Live Activity") .foregroundColor(.white) .padding() .background(Color.blue) .cornerRadius(10) }) } .padding() }}
#Preview { ContentView()}
- 创建一个 LiveActivityManager.swift 文件来管理 Live Activities
import Foundationimport ActivityKitimport UIKitimport PushwooshFrameworkimport PushwooshLiveActivities
class LiveActivityManager: NSObject, ObservableObject { public static let shared: LiveActivityManager = LiveActivityManager()
private var currentActivity: Activity<FoodDeliveryAttributes>? = nil
override init() { super.init() }
func startActivity() { guard ActivityAuthorizationInfo().areActivitiesEnabled else { print("You can't start live activity.") return } do { let pushwooshData = PushwooshLiveActivityAttributeData(activityId: "activity_id") let atttribute = FoodDeliveryAttributes(orderNumber: "1234567", pushwoosh: pushwooshData) let initialState = FoodDeliveryAttributes.ContentState( status: "Preparing your meal", estimatedTime: "25 min", emoji: "👨🍳", pushwoosh: nil ) let activity = try Activity<FoodDeliveryAttributes>.request( attributes: atttribute, content: .init(state:initialState , staleDate: nil), pushType: .token ) self.currentActivity = activity
Task { for await pushToken in activity.pushTokenUpdates { let pushTokenString = pushToken.reduce("") { $0 + String(format: "%02x", $1) } print("Activity:\(activity.id) push token: \(pushTokenString)")
// MARK: - Send Push Token to Pushwoosh Pushwoosh.LiveActivities.startLiveActivity( token: pushTokenString, activityId: "activity_id" ) } } } catch { print("Start Activity Error: \(error.localizedDescription)") } }}- 就是这样,现在我们运行项目并按下 ‘Start Live Activity’ 按钮。然后我们导航到锁定屏幕,就能看到已创建的 Live Activity。

通过远程推送通知启动实时活动
Anchor link to- 要通过远程推送通知启动 Live Activity,您需要将
pushToStartTokenUpdates令牌发送到 Pushwoosh。
func getPushToStartToken() { if #available(iOS 17.2, *) { Task { for await data in Activity<LiveActivityAttributes>.pushToStartTokenUpdates { let token = data.map {String(format: "%02x", $0)}.joined() print("Activity PushToStart Token: \(token)")
// Send `pushToStartTokenUpdates` token to Pushwoosh try await Pushwoosh.LiveActivities.sendPushToStartLiveActivity(token: token) } } }}- 通过远程推送通知启动 Live Activity
管理实时活动
Anchor link toPushwoosh iOS SDK 提供了以下用于处理 Live Activities 的方法:
// Send Live Activity Push To Start Token to Pushwooshstatic func sendPushToStartLiveActivity(token: String)static func sendPushToStartLiveActivity(token: String, completion: @escaping (Error?) -> Void)
// Start Live Activity Methods with Activity IDstatic func startLiveActivity(token: String, activityId: String)static func startLiveActivity(token: String, activityId: String, completion: @escaping (Error?) -> Void)
// Stop Live Activity Methodsstatic func stopLiveActivity()static func stopLiveActivity(completion: @escaping (Error?) -> Void)
static func stopLiveActivity(activityId: String)static func stopLiveActivity(activityId: String, completion: @escaping (Error?) -> Void)
// Schedule a Live Activity to start at a future date (iOS 26.0+)static func schedule<Attributes: PushwooshLiveActivityAttributes>(attributes: Attributes, contentState: Attributes.ContentState, at startDate: Date, alertTitle: String, alertBody: String) throws -> Activity<Attributes>
// Cancel a scheduled or running Live Activity by its Activity ID (iOS 16.2+)static func cancel<Attributes: PushwooshLiveActivityAttributes>(_ activityType: Attributes.Type, activityId: String)您还可以使用 Activity ID 参数按分段更新实时活动。创建活动时,您需要在方法中传递一个唯一的 Activity ID 参数,该参数将与特定的用户分段相关。
例如,N 个用户在 Live Activity 中订阅了同一个事件。Activity ID 参数对于所有这 N 个用户都必须是唯一的。
当您完成 Live Activity 的工作后,请使用以下方法:
static func stopLiveActivity()static func stopLiveActivity(completion: @escaping (Error?) -> Void)安排实时活动在未来日期启动
Anchor link to您可以安排 Live Activity 在未来某个日期启动,而不是立即启动。当计划的活动实际启动时,alertTitle 和 alertBody 会在本地通知警报中向用户显示:
if #available(iOS 26.0, *) { let startDate = Date().addingTimeInterval(3600) // starts in 1 hour
do { let activity = try Pushwoosh.LiveActivities.schedule( attributes: atttribute, contentState: initialState, at: startDate, alertTitle: "Game starting!", alertBody: "The match is about to begin" ) self.currentActivity = activity } catch { print("Schedule Activity Error: \(error.localizedDescription)") }}startDate 必须是未来的时间,否则调用会抛出错误。在应用处于前台时,在主线程上调用 schedule。没有向 Pushwoosh 发出安排时间的请求:服务器在活动实际启动并通过 setup() 方法安装的相同令牌观察者接收其推送令牌时才会知道该活动(见下文)。
通过活动 ID 取消实时活动
Anchor link to使用 cancel(_:activityId:) 可以通过其活动 ID 取消 Live Activity,而无需持有对 Activity 实例的引用:
if #available(iOS 16.2, *) { Pushwoosh.LiveActivities.cancel(FoodDeliveryAttributes.self, activityId: "activity_id")}cancel 会立即在设备上结束活动并通知 Pushwoosh 服务器。这与 stopLiveActivity(activityId:) 不同,后者只通知服务器,并不直接在设备上结束活动。cancel 也适用于已使用 schedule 安排但尚未开始的 Live Activity——它会在开始前被取消。
Setup() 方法。
Anchor link toPushwoosh 通过引入 PushwooshLiveActivities.setup 函数简化了活动 ID 的传输,该函数处理应用内 Live Activity 的整个生命周期。此函数会自动侦听 pushToStart 和 pushToUpdate 令牌更新。通过使用此方法,应用不再需要手动跟踪 Live Activities 的启动或管理活动更新的令牌更新。
我们建议使用此方法,因为它会处理我们这边的所有令牌管理,减少了您需要维护的代码量。这简化了集成,并确保您的应用获得更流畅、更高效的体验。
在 AppDelegate 中,确保导入 PushwooshFramework 和 PushwooshLiveActivities,并从 Pushwoosh.LiveActivities 模块调用 setup 方法。
AppDelegate.swift
if #available(iOS 16.1, *) { Pushwoosh.LiveActivities.setup(FoodDeliveryAttributes.self)}FoodDeliveryAttributes
import WidgetKitimport SwiftUIimport ActivityKitimport PushwooshFrameworkimport PushwooshLiveActivities
struct FoodDeliveryAttributes: PushwooshLiveActivityAttributes { public struct ContentState: PushwooshLiveActivityContentState { var status: String var estimatedTime: String var emoji: String var pushwoosh: PushwooshLiveActivityContentStateData? }
var orderNumber: String var pushwoosh: PushwooshLiveActivityAttributeData}FoodDeliveryAttributes:此结构符合 PushwooshLiveActivityAttributes 协议。它用于定义应用内实时活动的属性。
迁移指南
Anchor link to从 Pushwoosh iOS SDK 6.8.0 版本开始,我们更新了 SDK 结构。Live Activities 方法现在通过 PushwooshLiveActivities 模块访问。
如果您使用的是早于 6.8.0 版本的 Pushwoosh iOS SDK 并调用了下面列出的方法,并且此后已更新到 6.8.0 或更高版本,请注意以下更改:
static func setup<Attributes: PushwooshLiveActivityAttributes>(_ activityType: Attributes.Type)static func defaultSetup()static func defaultStart(_ activityId: String, attributes: [String: Any], content: [String: Any])现在,要访问这些方法,您应该使用 LiveActivity 模块。
import PushwooshFrameworkimport PushwooshLiveActivitiesPushwoosh.LiveActivities.setup(FoodDeliveryAttributes.self)Pushwoosh.LiveActivities.defaultSetup()Pushwoosh.LiveActivities.defaultStart("activity_id", attributes: ["key_attribute": "value_attribute"], content: ["key_content": "value_content"])我们还保留了通过 Pushwoosh.sharedInstance() 对下面列出的方法的支持,但请注意,这些方法将在未来版本中被弃用。
// Send Live Activity Push To Start Token to Pushwooshstatic func sendPushToStartLiveActivity(token: String)static func sendPushToStartLiveActivity(token: String, completion: @escaping (Error?) -> Void)
// Start Live Activity Methods with Activity IDstatic func startLiveActivity(token: String, activityId: String)static func startLiveActivity(token: String, activityId: String, completion: @escaping (Error?) -> Void)
// Stop Live Activity Methodsstatic func stopLiveActivity()static func stopLiveActivity(completion: @escaping (Error?) -> Void)
static func stopLiveActivity(activityId: String)static func stopLiveActivity(activityId: String, completion: @escaping (Error?) -> Void)