ActivityKit — 基础概念
This article is extracted from the chat log with AI. Please identify it with caution.

Apple 的 ActivityKit 是在 iOS 16 引入的一项框架,主要用于支持 Live Activities(实时活动) 的功能。它允许 App 在锁屏和动态岛(iPhone 14 Pro 及以上)中显示动态更新的实时信息,比如计程车到达时间、外卖配送状态、比赛比分等。

下面将系统性、详细地介绍 ActivityKit 的使用方式,包括其工作机制、关键组件、使用流程、注意事项和最佳实践。


🧠 一、ActivityKit 工作机制概览 #

Live Activities 是一种临时的信息展示,允许应用在 锁屏界面 和(支持的设备上)动态岛中展示活动状态,并通过推送或本地更新实时刷新内容。

  • 由 App 启动并控制展示

  • 可以通过 本地更新远程推送更新

  • 活动是临时的,最多持续 8 小时(可延长到 12 小时)

  • 用户可通过交互或系统事件(如结束导航)关闭活动


🧱 二、核心组成部分 #

ActivityKit 的使用主要依赖以下几个核心组成部分:

1. ActivityAttributes #

定义实时活动的静态和动态属性。

struct DeliveryAttributes: ActivityAttributes {
    public struct ContentState: Codable, Hashable {
        var estimatedDeliveryTime: Date
        var driverLocation: CLLocation
    }

    var orderID: String  // 静态属性
}
  • ContentState:表示会变化的内容,需实现 CodableHashable

  • 外层结构定义静态不变属性

2. Activity<Attributes> #

ActivityKit 提供的主要 API 接口,用于启动、更新、终止 Live Activity。


🧭 三、基本使用流程 #

步骤一:引入框架 #

import ActivityKit

步骤二:定义 ActivityAttributes #

struct TimerAttributes: ActivityAttributes {
    public struct ContentState: Codable, Hashable {
        var remainingTime: TimeInterval
    }

    var taskName: String
}

步骤三:启动一个 Activity #

let attributes = TimerAttributes(taskName: "Focus Timer")
let initialState = TimerAttributes.ContentState(remainingTime: 1500)

do {
    let activity = try Activity<TimerAttributes>.request(
        attributes: attributes,
        contentState: initialState,
        pushType: nil // 可为 .token 获取远程推送权限
    )
    print("Activity started with ID: \(activity.id)")
} catch {
    print("Failed to start activity: \(error)")
}

步骤四:更新 Activity #

Task {
    await activity.update(using: TimerAttributes.ContentState(remainingTime: 1400))
}

步骤五:结束 Activity #

Task {
    await activity.end(dismissalPolicy: .immediate)
}

📱 四、在 Widget Extension 中显示 Live Activity #

Live Activities 的 UI 是通过 Widget Extension 的新区域展示:

1. 创建 Widget Extension 并实现 ActivityConfiguration #

struct TimerLiveActivity: Widget {
    var body: some WidgetConfiguration {
        ActivityConfiguration(for: TimerAttributes.self) { context in
            // Lock screen / Dynamic Island expanded UI
            VStack {
                Text(context.attributes.taskName)
                Text("剩余时间: \(Int(context.state.remainingTime)) 秒")
            }
            .padding()
        } dynamicIsland: { context in
            DynamicIsland {
                DynamicIslandExpandedRegion(.leading) {
                    Text("⏳")
                }
                DynamicIslandExpandedRegion(.trailing) {
                    Text("\(Int(context.state.remainingTime))s")
                }
            } compactLeading: {
                Text("⏳")
            } compactTrailing: {
                Text("\(Int(context.state.remainingTime))s")
            } minimal: {
                Text("⏳")
            }
        }
    }
}

2. 配置 Extension #

Info.plist 中确保包含:

<key>NSExtension</key>
<dict>
    <key>NSExtensionAttributes</key>
    <dict>
        <key>com.apple.widgetkit.live-activity</key>
        <true/>
    </dict>
    <key>NSExtensionPointIdentifier</key>
    <string>com.apple.widgetkit-extension</string>
</dict>

📡 五、远程推送更新(可选) #

如果你想通过服务器远程更新 Live Activity,需要:

1. 开启 Push Type #

let activity = try Activity<TimerAttributes>.request(
    attributes: attributes,
    contentState: initialState,
    pushType: .token
)

2. 获取推送令牌(token) #

if let token = activity.pushToken {
    let tokenString = token.map { String(format: "%02x", $0) }.joined()
    // 发送给服务器用于后续推送
}

3. 服务器推送格式(HTTP POST) #

{
  "aps": {
    "timestamp": 1680000000,
    "event": "update",
    "content-state": {
      "remainingTime": 900
    }
  }
}

并发送至 Apple Live Activities 推送服务器的对应 URL。


🚧 六、注意事项和最佳实践 #

  1. 设备支持限制

    • Live Activities 显示在锁屏:iPhone 支持 iOS 16.1+

    • 动态岛:仅支持 iPhone 14 Pro 及以上

  2. 生命周期管理

    • 系统可能因内存、时间等原因中断 Live Activity

    • 最多可运行 8 小时(后台延长到 12 小时)

  3. 数据同步策略

    • 使用后台任务或本地定时器定期更新状态

    • 网络活动应谨慎管理,避免频繁请求

  4. UI 简洁性

    • 尽量简洁明了,不要塞入复杂交互或大量文本

    • 避免动画滥用,关注用户信息获取效率


🧪 七、测试与调试 #

  • 模拟器 中无法测试动态岛功能,需使用真机

  • 可以通过 Xcode 的 Live Activity Debugger 查看当前 Activity

  • 使用 activity.id 追踪调试状态

本文共 1154 字,创建于 May 19, 2025
相关标签: Xcode, ByAI, SwiftUI, ChatGPT