> ## Documentation Index
> Fetch the complete documentation index at: https://documentation.onesignal.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Live Activities 开发者设置

> 学习如何在您的 iOS 应用上使用 OneSignal 设置 Live Activities 以显示实时更新。

Live Activities 让您的 iOS 应用直接在锁屏和动态岛上显示实时更新。非常适合配送跟踪、体育比分或时效性交易更新，让用户无需打开应用即可保持了解。

<Note> Android 有一个类似的功能叫做 [Android Live Notifications](./android-live-notifications)。 </Note>

## 要求

* 如果使用原生 iOS（Swift/Objective-C），请遵循 [iOS SDK 设置](./ios-sdk-setup)。
  * 如果使用包装 SDK（React Native、Flutter、Unity 等），请遵循[移动 SDK 设置](./mobile-sdk-setup)，然后遵循[跨平台 Live Activity SDK 设置](./cross-platform-live-activity-setup)。
* OneSignal iOS SDK 版本 5.2.0+ 用于 **push-to-start** 支持（[查看发布说明](https://github.com/OneSignal/OneSignal-iOS-SDK/releases/tag/5.2.0)）。
* OneSignal iOS SDK 版本 5.2.15+ 用于 **点击跟踪** 和 **确认投递**
* iOS 16.1+ 和 iPadOS 17+
* 使用 [.p8 APNs 密钥](./ios-p8-token-based-connection-to-apns)。Apple 不支持在 Live Activities 中使用 p12 证书。
* Xcode 14 或更高版本

***

## 设置

这些步骤引导您快速设置 Live Activities。有关更多详情和设计自定义，请参阅 [Apple 的 Live Activities 开发者文档](https://developer.apple.com/design/human-interface-guidelines/live-activities)。

### 1. 添加 Widget 扩展

在 Xcode 中，转到 **File > New > Target... > Widget Extension**。

<Frame caption="在 Xcode 中为您的应用添加新的 Widget Extension 目标。">
  <img src="https://mintcdn.com/onesignal/FXJz6yFfOqztaEND/images/live-activities/live-activity-widget-extension.png?fit=max&auto=format&n=FXJz6yFfOqztaEND&q=85&s=60a52d6484203c4d6af21bc3a7da5e62" width="2166" height="1488" data-path="images/live-activities/live-activity-widget-extension.png" />
</Frame>

选择并按 **Next**。

通过提供名称（示例：`OneSignalWidget`）配置 Widget Extension，并确保选中 **Include Live Activity**。然后点击 **Finish**。

<Frame caption="Live Activity 的 Widget Extension 选项。">
  <img src="https://mintcdn.com/onesignal/yt4lRKoquAlWvRvF/images/live-activities/OneSignalWidget.png?fit=max&auto=format&n=yt4lRKoquAlWvRvF&q=85&s=47412314963f6fbd58fd2c7d3a529322" width="2166" height="1488" data-path="images/live-activities/OneSignalWidget.png" />
</Frame>

Click **Don't Activate** if prompted to activate the scheme.

<Frame caption="Live Activity 的 Widget Extension 选项。">
  <img src="https://mintcdn.com/onesignal/yt4lRKoquAlWvRvF/images/live-activities/la-scheme-activation.png?fit=max&auto=format&n=yt4lRKoquAlWvRvF&q=85&s=d3a2207ff2b5988c63c2abd631a72541" width="2166" height="1488" data-path="images/live-activities/la-scheme-activation.png" />
</Frame>

### 2. 更新 `Info.plist`

在您的主目标的 `Info.plist` 中，添加键 `Supports Live Activities` 作为 **Boolean**，并将其设置为 `YES`。

<Frame caption="将 Supports Live Activities 键添加到 Info 并将其值设置为布尔值 YES">
  <img src="https://mintcdn.com/onesignal/yt4lRKoquAlWvRvF/images/live-activities/info-la-setting.png?fit=max&auto=format&n=yt4lRKoquAlWvRvF&q=85&s=e839231401651b71d0ae8d48614ec130" width="2166" height="1488" data-path="images/live-activities/info-la-setting.png" />
</Frame>

如果您以编程方式设置它，应该如下所示：

```xml info.plist theme={null}
<key>NSSupportsLiveActivities</key>
<true/>
```

<Note>
  更新 Live Activities 时，您可以选择设置"优先级"，Apple 使用它来确定更新的紧急程度。Apple 有内部阈值，会对过于频繁使用高优先级标志的请求进行限制。

  如果您的 Live Activities 用例依赖于更频繁的高优先级更新，您可以按照 [Apple 开发者文档](https://developer.apple.com/documentation/activitykit/starting-and-updating-live-activities-with-activitykit-push-notifications#Determine-the-update-frequency)的指示，将键 `NSSupportsLiveActivitiesFrequentUpdates` 作为布尔类型设置为 YES 添加到您的 Info.plist 中。当 Live Activity 超过其推送预算时，用户将看到一个对话框，如果他们允许 Live Activity 继续，预算将自动增加以提供无缝的用户体验。
</Note>

### 3. 添加 SDK

<Tabs>
  <Tab title="包管理器">
    <Note>
      如果您使用的是包装 SDK（例如 **Flutter**）并启用了 SPM，可以跳过此步骤。OneSignal 包已解析并可供所有目标使用。
    </Note>

    在您的 Widget Extension 目标中，在**General > Frameworks, Libraries and Embedded Content**下添加 `OneSignalFramework`：

    <Frame caption="将 OneSignalFramework 添加到您的 Widget Extension 目标">
      <img src="https://mintcdn.com/onesignal/yt4lRKoquAlWvRvF/images/live-activities/add-one-signal-framework.png?fit=max&auto=format&n=yt4lRKoquAlWvRvF&q=85&s=386781616958e5a80a5cfec5ee143dcb" width="2392" height="1488" data-path="images/live-activities/add-one-signal-framework.png" />
    </Frame>
  </Tab>

  <Tab title="Cocoapods">
    在您项目的 Targets 列表中找到您的 widget extension 目标的名称。示例名称是 `OneSignalWidgetExtension`。

    <Frame caption="查找您的 widget extension 目标的名称">
      <img src="https://mintcdn.com/onesignal/yt4lRKoquAlWvRvF/images/live-activities/cocoapods-la-extension-name.png?fit=max&auto=format&n=yt4lRKoquAlWvRvF&q=85&s=850a91387539587802306a66771435eb" width="2166" height="1488" data-path="images/live-activities/cocoapods-la-extension-name.png" />
    </Frame>

    打开您的 `Podfile` 并添加以下代码。将 `OneSignalWidgetExtension` 替换为您的 widget extension 目标的名称。

    <CodeGroup>
      ```ruby Podfile theme={null}
      target 'OneSignalWidgetExtension' do
        use_frameworks!
        pod 'OneSignal/OneSignal', '>= 5.0.0', '< 6.0'
      end
      ```

      ```ruby Full Podfile example theme={null}
      # Uncomment the next line to define a global platform for your project
      # platform :ios, '9.0'

      target 'Demo Momenta' do
        # Comment the next line if you don't want to use dynamic frameworks
        use_frameworks!
        pod 'OneSignal/OneSignal', '>= 5.0.0', '< 6.0'
        pod 'OneSignal/OneSignalInAppMessages', '>= 5.0.0', '< 6.0'
      end

      target 'OneSignalNotificationServiceExtension' do
        use_frameworks!
        pod 'OneSignal/OneSignal', '>= 5.0.0', '< 6.0'
      end

      target 'OneSignalWidgetExtension' do
        use_frameworks!
        pod 'OneSignal/OneSignal', '>= 5.0.0', '< 6.0'
      end
      ```
    </CodeGroup>

    关闭 Xcode 并运行 `pod repo update && pod install` 来安装 `OneSignalLiveActivities` pod。

    如果在执行此操作后仍然看到"No such module 'OneSignalLiveActivities'"错误，您可以通过转到您的 **"Widget Extension Target" > General > Frameworks and Libraries > + icon** 手动添加依赖项。选择 `OneSignalLiveActivities` 框架：

    <Frame caption="手动添加依赖项">
      <img src="https://mintcdn.com/onesignal/YOTSrtBSoqdrJ37A/images/docs/427d54ef84e97edaf0a7c3b158b48b3bec7305fb1764db9dd4ef7c340d77bc6c-image.png?fit=max&auto=format&n=YOTSrtBSoqdrJ37A&q=85&s=f7ba0aa4234ef69ebd7820ef5e50a18b" width="1273" height="881" data-path="images/docs/427d54ef84e97edaf0a7c3b158b48b3bec7305fb1764db9dd4ef7c340d77bc6c-image.png" />
    </Frame>
  </Tab>
</Tabs>

### 4. 定义小组件属性和 UI

打开 `your-nameLiveActivity.swift` 文件（示例：`OneSignalWidgetLiveActivity.swift`）来定义结构的属性并对 widget UI 进行更改。

* `your-nameAttributes` 描述您 Live Activity 的静态内容。
* `ContentState` 描述您 Live Activity 的动态内容。

如果您遵循示例，请将下面的代码复制粘贴到您的 `OneSignalWidgetLiveActivity.swift` 文件中。

```swift your-nameLiveActivity.swift theme={null}
import ActivityKit
import WidgetKit
import SwiftUI
// 导入 OneSignalLiveActivities 模块
// 如果您收到关于找不到模块的错误，请返回步骤 3 并确保您已正确添加了 OneSignalLiveActivities pod。
import OneSignalLiveActivities

// 更新以继承 OneSignalLiveActivityAttributes
// 这将在您的 API 请求中用于启动 Live Activity
struct OneSignalWidgetAttributes: OneSignalLiveActivityAttributes  {
    // 更新以继承 OneSignalLiveActivityContentState
    public struct ContentState: OneSignalLiveActivityContentState {
        // 关于您活动的动态状态属性在这里！
        var emoji: String
        // 添加对 OneSignalLiveActivityContentStateData 的引用？
        var onesignal: OneSignalLiveActivityContentStateData?
    }
    // 关于您活动的固定不变属性在这里！
    var name: String
    // 添加对 OneSignalLiveActivityAttributeData 的引用
    var onesignal: OneSignalLiveActivityAttributeData
}

struct OneSignalWidgetLiveActivity: Widget {
    var body: some WidgetConfiguration {
      // 更新以使用 `for: the-name-of-your-attributes-struct`
      // 这将在您的 API 请求中用于启动 Live Activity
        ActivityConfiguration(for: OneSignalWidgetAttributes.self) { context in
            // 锁屏/横幅 UI 在这里
            // 更新以显示通过负载发送的属性
            VStack {
                Text("Hello \(context.attributes.name) \(context.state.emoji)")
            }
            .activityBackgroundTint(Color.cyan)
            .activitySystemActionForegroundColor(Color.black)

        } dynamicIsland: { context in
            DynamicIsland {
                // 展开的 UI 在这里。通过各种区域组成展开的 UI，
                // 如 leading/trailing/center/bottom
                DynamicIslandExpandedRegion(.leading) {
                    Text("Leading")
                }
                DynamicIslandExpandedRegion(.trailing) {
                    Text("Trailing")
                }
                DynamicIslandExpandedRegion(.bottom) {
                    Text("Bottom \(context.state.emoji)")
                    // 更多内容
                }
            } compactLeading: {
                Text("L")
            } compactTrailing: {
                Text("T \(context.state.emoji)")
            } minimal: {
                Text(context.state.emoji)
            }
            .widgetURL(URL(string: "http://www.apple.com"))
            .keylineTint(Color.red)
        }
    }
}
```

### 5. 允许主目标成员资格

<Note>
  此步骤仅在使用自定义属性（例如 `OneSignalWidgetAttributes`）时需要。如果您使用的是 `DefaultLiveActivityAttributes`，请跳过此步骤——该类型由 OneSignal SDK 提供，已可从主应用目标访问。
</Note>

将您的主应用目标添加到 `your-nameLiveActivity.swift` 文件中的 **Target Membership** 列表。这是必要的，以便主应用目标可以在设置调用（步骤 6）中引用您的自定义属性结构体。

在 Xcode 中，打开屏幕右侧的 Inspector 面板。在 **Target Membership** 中，点击 **+** 按钮并选择包含 `ContentView` 和您的 OneSignal 初始化代码的主应用目标。

<Frame caption="允许主目标成员资格">
  <img src="https://mintcdn.com/onesignal/FXJz6yFfOqztaEND/images/live-activities/target-membership.png?fit=max&auto=format&n=FXJz6yFfOqztaEND&q=85&s=3315253623dfec6c13a56ff30a156772" width="2392" height="1488" data-path="images/live-activities/target-membership.png" />
</Frame>

### 6. 将设置方法添加到您的 AppDelegate

在 OneSignal SDK 初始化后，在您的 `AppDelegate` 中调用 `OneSignal.LiveActivities.setup`。

将 `OneSignalWidgetAttributes` 替换为您的 Live Activity 属性结构的名称。

```swift AppDelegate theme={null}
// 导入 OneSignalLiveActivities 模块
import OneSignalLiveActivities

// 这应该在初始化 OneSignal SDK 后添加
if #available(iOS 16.1, *) {
	OneSignal.LiveActivities.setup(OneSignalWidgetAttributes.self)
  // 如果您有多个 Live Activities，您可以在这里使用 setup 方法添加它们
  // OneSignal.LiveActivities.setup(LiveActivityWidgetAttributes-2.self)
}
```

这使用 ActivityKit 异步序列管理和报告更新。

<Warning>
  如果您在应用中也直接使用以下任何序列，可能会干扰 OneSignal Live Activity 行为：

  * activityStateUpdates
  * pushTokenUpdates
  * pushToStartTokenUpdates
  * activityUpdates
</Warning>

***

## 启动 Live Activity

在设备上启动 Live Activity 有 2 个选项：

<Tabs>
  <Tab title="推送开始">
    发送[推送启动 API 请求](/reference/start-live-activity)。确保所有名称和 ID 与您的 widget 配置完全匹配（参数区分大小写）。如果有任何遗漏或错误添加，您在尝试启动 widget 时可能会遇到问题。

    这是一个适用于上述示例的示例请求。

    替换：

    * `YOUR_APP_ID` 为您的 OneSignal 应用 ID。
    * `YOUR_APP_API_KEY` 为您的 OneSignal API 密钥。
    * `OneSignalWidgetAttributes` 为您的 Widget Attributes 结构的名称。

      ```curl curl theme={null}
      curl --location 'https://api.onesignal.com/apps/YOUR_APP_ID/activities/activity/OneSignalWidgetAttributes' \
      --header 'Authorization: key YOUR_APP_API_KEY' \
      --header 'Content-Type: application/json' \
      --data '{
          "event": "start",
          "activity_id": "push-to-start",
          "included_segments": [
              "Subscribed Users"
          ],
          "event_attributes": {
              "name": "World"
          },
          "event_updates": {
              "emoji":"🤩"
          },
          "name": "Live Activities Test",
          "contents": {
              "en": "A push started this Live Activity"
          },
          "headings": {
            "en": "Live Activity Started"
          }
        }'
      ```

    如果您遵循提供的示例代码，您应该在设备的锁屏上看到 Live Activity。

    <Frame caption="锁屏上的 Live Activity">
      <img src="https://mintcdn.com/onesignal/FXJz6yFfOqztaEND/images/live-activities/live-activity-lock-screen.jpg?fit=max&auto=format&n=FXJz6yFfOqztaEND&q=85&s=8abc098ce8772b1c457e5f1effc8c14e" width="900" height="385" data-path="images/live-activities/live-activity-lock-screen.jpg" />
    </Frame>

    <Check>
      您已成功使用 push-to-start 启动了 Live Activity！

      用户需要选择"允许"以继续获取更新。
    </Check>
  </Tab>

  <Tab title="应用内触发">
    您可以让用户在与您的应用交互时触发 Live Activity。

    例如，当用户有活动事件进行中（他们下了订单、游戏正在进行、事件即将开始等）并打开您的应用时，您可以自动显示 Live Activity。

    在此示例中，我们将使用按钮手动启动 Live Activity。

    ```swift theme={null}
    import SwiftUI
    import ActivityKit
    import OneSignalFramework
    import OneSignalLiveActivities

    struct ContentView: View {
      @StateObject private var viewModel = LiveActivityViewModel()

      var body: some View {
        VStack {
          Button("Start Live Activity") {
            viewModel.startLiveActivity()
          }
        }
      }
    }

    class LiveActivityViewModel: ObservableObject {

      func startLiveActivity() {
        let osAttributes = OneSignalLiveActivityAttributeData.create(activityId: "click-to-start")
        let attributes = OneSignalWidgetAttributes(name: "OneSignal", onesignal: osAttributes)
        let contentState = OneSignalWidgetAttributes.ContentState(emoji:"🤩", onesignal: nil)
        do {
            let activity = try Activity<OneSignalWidgetAttributes>.request(
                attributes: attributes,
                contentState: contentState,
                pushType: .token)
        } catch {
            print(error.localizedDescription)
        }
      }
    }
    ```

    点击按钮后它将启动 Live Activity。
  </Tab>
</Tabs>

***

## 跟踪 Live Activity 点击

通过实施 OneSignal 的点击跟踪来跟踪用户何时点击您的 Live Activities 和动态岛。这使您能够测量参与度并可选择将用户深度链接到应用中的特定内容。

### 步骤 1：向您的 Widget 添加点击跟踪

将 `.onesignalWidgetURL()` 修饰符添加到您 Live Activity widget 中希望跟踪点击的任何 UI 组件：

```swift theme={null}
import OneSignalLiveActivities

struct ExampleAppFirstWidget: Widget {
    var body: some WidgetConfiguration {
        ActivityConfiguration(for: ExampleAppFirstWidgetAttributes.self) { context in
            VStack {
                Spacer()
                Text("Sample Text " + context.attributes.title).font(.headline)
                // 其他 UI 代码
            }
            .onesignalWidgetURL(URL(string: "myapp://settings"), context: context)
            // 如果您不需要深度链接，请传递 nil：.onesignalWidgetURL(nil, context: context)
        } dynamicIsland: { context in
            DynamicIsland {
                DynamicIslandExpandedRegion(.leading) {
                    Text("Leading")
                }
                // 其他动态岛区域
            } compactLeading: {
                Text("L")
            } compactTrailing: {
                Text("T")
            } minimal: {
                Text("Min")
            }
            .onesignalWidgetURL(URL(string: "myapp://settings"), context: context)
            // 可选：单独跟踪动态岛点击
        }
    }
}
```

**重要注意事项：**

* 您可以传递用于深度链接的 URL，或者如果您只想跟踪点击而无需导航，则传递 `nil`
* 如果您使用 `.onesignalWidgetURL()`，视图层次结构**不能包含** Apple 的 `.widgetURL()` 修饰符
* 如果您想跟踪两者的点击，请将修饰符应用于主 Live Activity 视图和动态岛

### 步骤 2：在您的应用中处理 URL

在您的应用中添加 URL 处理以跟踪点击并适当路由用户：

```swift theme={null}
import OneSignalLiveActivities

// AppDelegate 示例：
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    let originalURL = OneSignal.LiveActivities.trackClickAndReturnOriginal(url)
    
    // 处理原始 URL 并导航用户
    if let url = originalURL {
        // 您的自定义 URL 路由逻辑
        return handleDeepLink(url)
    }
    return false
}

// SceneDelegate 示例：
func scene(_ scene: UIScene, openURLContexts URLContexts: Set) {
    guard let url = URLContexts.first?.url else { return }
    
    let originalURL = OneSignal.LiveActivities.trackClickAndReturnOriginal(url)
    
    if let url = originalURL {
        // 您的自定义 URL 路由逻辑
        handleDeepLink(url)
    }
}

// SwiftUI 示例：
.onOpenURL { url in
    let originalURL = OneSignal.LiveActivities.trackClickAndReturnOriginal(url)
    
    if let url = originalURL {
        // 您的自定义 URL 路由逻辑
        handleDeepLink(url)
    }
}
```

`trackClickAndReturnOriginal()` 方法自动使用 OneSignal 跟踪点击并返回您在 widget 中指定的原始 URL 供您的应用处理。

***

## 更新 Live Activity

使用[更新 Live Activity API](/reference/update-live-activity-api)来更新活动的 widgets。

匹配启动活动时使用的 `activity_id`。

此示例请求将更新 push-to-start widget，因为它具有我们定义的标题为 `push-to-start` 的 `activity_id`。
要更新 click-to-start widget，请更新请求路径以使用 `click-to-start` 而不是 `push-to-start`。

```curl curl theme={null}
curl --location 'https://api.onesignal.com/apps/YOUR_APP_ID/live_activities/push-to-start/notifications' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: key YOUR_API_KEY' \
--data '{
    "event": "update",
    "event_updates": {
        "emoji": "😎"
    },
    "contents": {
        "en": "A push updated this Live Activity"
    },
    "name": "Live Activity Updated"
}'
```

<Frame caption="Live Activity 已更新">
  <img src="https://mintcdn.com/onesignal/FXJz6yFfOqztaEND/images/live-activities/live-activity-updated.jpg?fit=max&auto=format&n=FXJz6yFfOqztaEND&q=85&s=729ab3b33c297c15e52617ebd065b293" width="895" height="152" data-path="images/live-activities/live-activity-updated.jpg" />
</Frame>

<Check>
  您已成功更新了 Live Activity！

  查看[更新 Live Activity API](/reference/update-live-activity-api)以获取有关更新 Live Activity 的更多信息。
</Check>

***

## 结束 Live Activity

使用相同的[更新 Live Activity API](/reference/update-live-activity-api)，我们可以通过设置 `"event": "end"` 来结束 Live Activity。

```curl curl theme={null}
curl --location 'https://api.onesignal.com/apps/YOUR_APP_ID/live_activities/my_activity_id/notifications' \
--header 'Content-Type: application/json' \
--header 'Accept: application/json' \
--header 'Authorization: key YOUR_API_KEY' \
--data '{
    "event": "end",
    "event_updates": {
        "emoji": "👋"
    },
    "contents": {
        "en": "A push ended this Live Activity"
    },
    "name": "Live Activity Ended"
}'
```

Live Activity 的其他结束方式：

* 使用我们的 SDK [`exit()` 方法](./mobile-sdk-reference#exit)。
* 用户手动滑动 Live Activity 使其消失。
* 用户在 iOS 设置中撤销 Live Activities 权限。

<Frame caption="Live Activity 已结束">
  <img src="https://mintcdn.com/onesignal/FXJz6yFfOqztaEND/images/live-activities/live-activity-ended.jpg?fit=max&auto=format&n=FXJz6yFfOqztaEND&q=85&s=734a62b67cb2fe989203087a22945448" width="1218" height="200" data-path="images/live-activities/live-activity-ended.jpg" />
</Frame>

<Check>
  您已成功结束 Live Activity 并完成了示例！
</Check>

***

## 最佳实践和建议

### 设计考虑

* 遵循 Apple 的 [Live Activities 人机界面指南](https://developer.apple.com/design/human-interface-guidelines/live-activities)。
  * 优先考虑重要信息，使其易于一目了然地理解。
  * 不要在您的应用中添加吸引对动态岛注意的元素。
  * 使用边距并保持元素之间的空间。
  * 为背景使用醒目的颜色。为浅色和深色模式进行设计。

### 功能性

* Apple 要求支持每个 [Live Activity 展示](https://developer.apple.com/documentation/activitykit/displaying-live-data-with-live-activities#Review-Live-Activity-presentations)。
  * [紧凑](https://developer.apple.com/design/human-interface-guidelines/live-activities#Compact-presentation)
  * [最小](https://developer.apple.com/design/human-interface-guidelines/live-activities#Minimal-presentation)
  * [展开](https://developer.apple.com/design/human-interface-guidelines/live-activities#Expanded-presentation)
  * [锁屏](https://developer.apple.com/design/human-interface-guidelines/live-activities#The-Lock-Screen)
* 测试您的[深度链接](https://developer.apple.com/design/human-interface-guidelines/live-activities#Offering-interactivity)。
* 查看 Apple 关于[使用 Live Activities 显示实时数据](https://developer.apple.com/documentation/activitykit/displaying-live-data-with-live-activities)的指南。
* 避免在 Live Activity 中显示敏感信息。

### 设置回退消息

* 在某些情况下，用户无法接收到 live activity 的更新（在已启动一个后），打开应用应该刷新它们以继续
  * 为了解决这个问题，您可以将[stale date](/reference/start-live-activity#body-stale-date)设置为未来的日期和时间，在您知道会向用户发送第一个更新后，那些没有收到更新的用户将显示回退消息。
  * 您可以在 widget UI 中监听这种"stale"状态以显示回退消息：
  <img src="https://mintcdn.com/onesignal/CKWnlQN-faoVTpm2/images/live-activities/live-activity-refresh.png?fit=max&auto=format&n=CKWnlQN-faoVTpm2&q=85&s=180ef1cc07313ef04361fbd45e2fec24" width="509" height="181" data-path="images/live-activities/live-activity-refresh.png" />

<CodeGroup>
  ```swift swift theme={null}
  struct ptsLiveActivity: Widget {
      var body: some WidgetConfiguration {
          ActivityConfiguration(for: ptsAttributes.self) { context in
              //这将在 stale date 后翻转为 true
              let isStale = context.isStale 
              if !isStale{
                  VStack {
                      Text("\(context.attributes.name) \(context.state.emoji)")
                          .activityBackgroundTint(Color.cyan)
                          .activitySystemActionForegroundColor(Color.black)
                  }
              }  else {
              //如果消息是陈旧的，我们要求用户点击 widget 来打开应用
                  VStack {
                      Text("出了问题，请点击刷新")
                  }
              }
          //... widget UI 的其余部分
          }
      }
  }
  ```
</CodeGroup>

***

## 常见问题

### 高优先级更新的预算是多少？

Apple 不为高优先级（`priority: 10`）更新提供固定限制，但他们确实执行动态系统级预算。在短时间内发送过多高优先级更新可能导致限制，更新被延迟或丢弃。

要降低限制风险：

* 使用混合优先级：Apple 建议同时使用 `priority: 5`（标准）和 `priority: 10`（高）以取得平衡。
* 仅为时效性或关键更新保留 `priority: 10`（如订单状态变化、游戏比分）。

如果您的用例需要频繁更新：

* 将键 `NSSupportsLiveActivitiesFrequentUpdates` 添加到您应用的 `Info.plist` 文件中，设置为布尔值 `YES`。
* 当超过此预算时，iOS 可能会提示用户允许额外更新。如果用户同意，Apple 将自动扩展允许的更新限制以保持无缝体验。

有关更多详情，请参阅 [Apple 开发者文档](https://developer.apple.com/documentation/activitykit/starting-and-updating-live-activities-with-activitykit-push-notifications#Determine-the-update-frequency)。

### 我可以从主应用读取 Live Activity 更新吗？

是的。您可以观察更新以进行调试或 UI 同步：

```swift theme={null}
Task {
    for await content in activity.contentUpdates {
        print("LA activity id: \(activity.id), content update: \(content.state)")
    }
}
// Example output:
// LA activity id: EFE6D54D-F7E1-45EF-9514-4C2598F8DED2, content update: ContentState(message: "My message from payload")
```

跟踪生命周期变化：

```swift theme={null}
Task {
    for await state in activity.activityStateUpdates {
        print("LA state update: \(state)")
        //If you wanted to do something based on the state, you would use this:
      	if state != ActivityState.active {
            //Do something here
        }
    }
}

// Example output 1 - LA ended, but still visible
// LA state update: active

/* State can be equal to 4 possible values on the ActivityState enum
active, dismissed, ended, and stale
*/
```

### API 返回 400 错误，提示我超过了订阅者限制。我该怎么办？

如果您的推送订阅者数量超过了您计划的推送订阅者限制，请将您的账户升级到下一个计划，或联系 `support@onesignal.com`。有关最新计划详情，[请点击这里查看](https://onesignal.com/pricing)。

### 如何避免同时发送推送和 Live Activities？

您的应用可能已经发送了一系列推送通知，而您设计的 Live Activity 替代了这些推送通知的需要。例如，如果您通过推送发送比分更新，您可以通过 Live Activity 来替代。

为了确保您的用户不会收到太多消息，我们建议当您的用户选择加入 Live Activity 时，添加一个数据标签。通过添加此数据标签，您可以从可能包含相同或类似内容的推送消息中排除具有此数据标签的用户。阅读更多关于[数据标签](./add-user-data-tags)和[细分](./segmentation)的信息。

***

## 故障排除

### 无接收者

为了在尝试启动或更新 Live Activity 时找到您的用户，您必须确保活动类型、widget 和 cURL 请求都具有匹配的值。

1. 检查请求中的路径参数，确保您向服务器发送的是格式正确的请求。应用 ID 必须与您在 `OneSignal.Initialize` 方法中使用的应用 ID 匹配，活动类型必须与您在 Live Activity 文件中定义的类型匹配。

2. 在[推送启动 API 请求](/reference/start-live-activity)的主体中，您应该具有以下参数：

* `event`: `"start"`
* `event_updates`: 您在活动类型下的结构中定义的并在您的 widget 中使用的动态数据。确保请求、类型和 widget 之间的字母大小写和变量都匹配。
* `event_attributes`: 静态数据遵循与事件更新相同的逻辑，必须包含使用中的所有变量，并且必须在 live activity 和请求的所有部分中匹配
* `activity_id`: 这将为 widget 分配一个 ID，是在用户设备上启动活动后用于更新活动的 ID。
* `name`: Live Activity 名称。
* `contents`: 发送推送所需的消息内容。
* `headings`: 发送推送所需的消息标题。
* 定向参数，如 `included_segments`。[可用选项](/reference/create-message)。

### 活动已发送但未接收

1. 确保请求格式正确。如果省略了 Widget 中使用的任何字段，活动可能无法按预期启动或更新。

2. 在您的 API 请求中，确定您设置的 `priority` 级别。如果您将其设置为 `10`（最高优先级），请尝试将其降低到 `5` 并重新测试。Apple 会根据他们自己的内部速率限制对发送过于频繁的请求进行限制。

如果您的用例依赖于更频繁的更新，请按照 [Apple 开发者文档](https://developer.apple.com/documentation/activitykit/starting-and-updating-live-activities-with-activitykit-push-notifications#Determine-the-update-frequency)的指示，将键 `NSSupportsLiveActivitiesFrequentUpdates` 作为布尔类型设置为 YES 添加到您的 Info.plist 中。当 Live Activity 超过其推送预算时，用户将看到一个对话框，如果他们允许 Live Activity 继续，预算将自动增加以提供无缝的用户体验。

<Info>
  需要帮助？

  与我们的支持团队聊天或发送邮件至 `support@onesignal.com`

  请包含以下信息：

  * 您遇到的问题详情以及复现步骤（如有）
  * 您的 OneSignal 应用 ID
  * 外部 ID 或订阅 ID（如适用）
  * 您在 OneSignal 控制台中测试的消息 URL（如适用）
  * 任何相关的[日志或错误信息](/docs/cn/capturing-a-debug-log)

  我们很乐意为您提供帮助！
</Info>

***
