> ## 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.

# 确认送达

> 确认送达跟踪设备接收到通过OneSignal发送的推送通知的时间。涵盖iOS、Android、Huawei和Web的要求、平台限制和故障排除。

## 概览

确认送达跟踪设备是否真正**接收**到通过OneSignal发送的推送通知。当设备上的OneSignal SDK收到推送时，它会将包含通知ID和设备[订阅ID](./subscriptions)的确认事件发送回OneSignal。这让您可以确切地看到哪些订阅收到了哪些通知。

在您的OneSignal仪表板中，确认送达在[消息报告](./push-notification-message-reports)中显示为**已确认**（或**已接收**）。有关所有送达和参与指标，请参阅[指标词汇表](./analytics-metrics-glossary)。

<Frame caption="确认送达流程">
  <img src="https://mintcdn.com/onesignal/_KaXe4GQkxsEfa17/images/docs/35ba167-analytics-ensure-confirmed-message-delivery_1.png?fit=max&auto=format&n=_KaXe4GQkxsEfa17&q=85&s=17ce8f50b8e92e0d368abe42865709c3" alt="确认送达流程" width="800" height="667" data-path="images/docs/35ba167-analytics-ensure-confirmed-message-delivery_1.png" />
</Frame>

<Note>
  确认送达与"已送达"不同。平台推送服务（APNs、FCM、ADM、HMS）报告通知是否被服务接受——而不是设备是否实际收到了它。确认送达是设备端的确认。
</Note>

***

## 要求

* 仅在**付费计划**中提供。[比较计划](https://onesignal.com/pricing)。
* 完成[Web SDK设置](./web-sdk-setup)和/或[移动SDK设置](./mobile-sdk-setup)。
  * 确认送达仅在设备安装了OneSignal SDK时才有效。
  * **不支持**仅通过API创建的订阅。

### 平台特定限制

**iOS**

* 需要**Notification Service Extension**和**App Group**两者的设置。
* APNs在离线时每个应用仅保留**一条消息**。如果离线时发送了多条推送，则仅送达最新的一条。

**Huawei**

* 仅支持`data` [华为消息类型](/reference/push-notification#body-huawei-msg-type)。
* 对于`message`类型，华为仅在其自己的仪表板中提供回执数据。

**Web**

* Safari**不**支持确认送达。

***

## 确认送达故障排除

如果您根本没有收到推送通知，请先参阅[通知未显示](./notifications-show-successful-but-are-not-being-shown)。

### iOS

iOS上的确认送达需要两件事协同工作：

1. 推送到达时运行OneSignal代码的**Notification Service Extension**（NSE）
2. 在主应用目标和NSE目标之间共享的**App Group**，使它们能够交换数据

如果任何一个缺失或配置错误，设备会收到推送但从不向OneSignal报告。

**验证您的iOS设置**

<Steps>
  <Step title="确认NSE目标存在并具有正确的代码">
    在Xcode中，检查项目目标下是否列出了**OneSignalNotificationServiceExtension**目标。如果不存在，请按照[iOS SDK设置的第2步](./ios-sdk-setup#step-2-add-a-notification-service-extension-nse)操作。

    打开NSE的`NotificationService.swift`（或`.m`）文件。它必须在`didReceive(_:withContentHandler:)`内调用`OneSignalExtension.didReceiveNotificationExtensionRequest`。如果文件仍包含Apple的默认模板代码，请将其替换为[OneSignal NSE代码](./ios-sdk-setup#step-2-add-a-notification-service-extension-nse)。
  </Step>

  <Step title="确认NSE具有OneSignalExtension包">
    选择您的**NSE目标 > General > Frameworks and Libraries**（或**Build Phases > Link Binary With Libraries**）。验证`OneSignalExtension`已列出。主应用目标使用`OneSignalFramework`，但NSE目标必须使用`OneSignalExtension`——这些是不同的包。
  </Step>

  <Step title="验证App Group在两个目标上都已正确配置">
    OneSignal SDK使用App Group在主应用和NSE之间共享数据。有两种配置方式——选择与您的设置匹配的一种。

    1. 选择您的**主应用目标 > Signing & Capabilities > App Groups**。
    2. 确认App Group。

    如果您的App Group是`group.YOUR_MAIN_APP_BUNDLE_ID.onesignal`——其中`YOUR_MAIN_APP_BUNDLE_ID`是主应用目标的Bundle Identifier（在**General > Identity**下可找到），请按照默认App Group选项卡操作。否则，请按照自定义App Group选项卡操作。

    <Tabs>
      <Tab title="默认App Group - group.YOUR_MAIN_APP_BUNDLE_ID.onesignal">
        1. 选择您的**NSE目标 > Signing & Capabilities > App Groups**。
        2. 确认**完全相同**的App Group已列出。如果缺少，通过\*\*+ Capability > App Groups\*\*添加并选择相同的组。

        常见错误是使用NSE的bundle identifier而不是主应用的：

        * **正确：** `group.YOUR_MAIN_APP_BUNDLE_ID.onesignal`
        * **错误：** `group.YOUR_MAIN_APP_BUNDLE_ID.OneSignalNotificationServiceExtension.onesignal`

        您的主应用目标和NSE目标应具有相同的App Group标识符。
      </Tab>

      <Tab title="自定义App Group">
        如果您的App Group标识符不遵循`group.YOUR_MAIN_APP_BUNDLE_ID.onesignal`格式，请使用此选项。

        1. 选择您的**主应用目标 > Signing & Capabilities > App Groups**。
        2. 确认您的自定义App Group已列出。
        3. 选择主应用目标的`Info.plist`并添加以下键：

        ```xml theme={null}
        <key>OneSignal_app_groups_key</key>
        <string>group.your-custom-group-name</string>
        ```

        将`group.your-custom-group-name`替换为您实际的App Group名称。

        4. 选择您的**NSE目标 > Signing & Capabilities > App Groups**。
        5. 确认**完全相同**的自定义App Group已列出。如果缺少，通过\*\*+ Capability > App Groups\*\*添加并选择相同的组。
        6. 选择NSE目标的`Info.plist`并添加以下键：

        ```xml theme={null}
        <key>OneSignal_app_groups_key</key>
        <string>group.your-custom-group-name</string>
        ```

        将`group.your-custom-group-name`替换为您实际的App Group名称。

        您的主应用目标和NSE目标应具有相同的App Group标识符。
      </Tab>
    </Tabs>

    <Warning>
      如果您使用`.xcconfig`文件进行构建设置，请验证App Group没有在这些文件中被覆盖或省略。
    </Warning>
  </Step>

  <Step title="确认最低部署目标匹配">
    选择您的**NSE目标 > General > Minimum Deployments**。此值必须与主应用目标的最低部署相匹配。不匹配可能会导致NSE在某些操作系统版本上无法运行。
  </Step>

  <Step title="取消勾选&#x22;Copy only when installing&#x22;">
    选择您的**主应用目标 > Build Phases > Embed App Extensions**。确保**取消勾选"Copy only when installing"**。如果勾选，NSE在开发构建期间不会被嵌入，因此在测试时永远不会运行。
  </Step>

  <Step title="验证Info.plist中的NSExtension值">
    选择您的**NSE目标 > Info选项卡**并展开`NSExtension`键。确认它包含：

    ```xml theme={null}
    <key>NSExtensionPointIdentifier</key>
    <string>com.apple.usernotifications.service</string>
    <key>NSExtensionPrincipalClass</key>
    <string>$(PRODUCT_MODULE_NAME).NotificationService</string>
    ```

    如果您的NSE是用Objective-C编写的，请使用`NotificationService`而不是`$(PRODUCT_MODULE_NAME).NotificationService`。
  </Step>

  <Step title="验证mutable-content已设置">
    OneSignal自动在推送有效载荷中设置`mutable-content: 1`，这告诉iOS调用NSE。如果您通过[REST API](/reference/push-notification)发送推送，请验证您没有明确设置`mutable_content: false`。没有`mutable-content`，iOS不会运行NSE，确认送达就无法触发。
  </Step>

  <Step title="测试NSE是否正在运行">
    在OneSignal调用之前，临时在`didReceive`内添加这一行：

    ```swift theme={null}
    bestAttemptContent.body = "[Modified] " + bestAttemptContent.body
    ```

    向自己发送一条测试推送。如果通知正文以`[Modified]`开头，则NSE运行正常。如果没有，请重新检查上述步骤——NSE未被调用。测试后删除此行。

    有关使用Xcode Console日志进行高级NSE调试，请参阅[调试iOS Notification Service Extension](./service-extensions#debugging-the-ios-notification-service-extension)。
  </Step>
</Steps>

### Android

* 如果通知未显示：请参阅[移动推送故障排除](./notifications-show-successful-but-are-not-being-shown)。
* 如果通知显示但确认送达缺失：自定义Android Service Extension可能正在阻止它。查看[Android Service Extension指南](./service-extensions#android-service-extension)。

### Web

* Safari不受支持。
* 对于其他浏览器，确保迁移到**v16 SDK**已完成：
  * 正确的SDK初始化：
    ```html theme={null}
    <script src="https://cdn.onesignal.com/sdks/web/v16/OneSignalSDK.page.js" defer></script>
    ```
  * 正确的Service Worker引用：
    ```html theme={null}
    importScripts("https://cdn.onesignal.com/sdks/web/v16/OneSignalSDK.sw.js");
    ```

***

## 常见问题

### 为什么我的确认送达数量很低或没有显示？

最常见的原因是设置问题（尤其是iOS）、不活跃设备和平台限制。

1. **iOS配置错误：** Notification Service Extension或App Group缺失或不正确。请参阅上面的[iOS确认送达故障排除](#ios)。
2. **不活跃或废弃的设备：** 离线或不再使用的设备不会接收推送或发送确认送达事件。请参阅下面的[如何处理不活跃设备？](#如何处理不活跃设备)。
3. **平台限制：** 华为`message`类型和Safari不支持确认送达。
4. **Android强制退出：** 某些设备制造商将划走应用视为强制退出，这会停止SDK事件。请参阅[移动推送未显示指南](./notifications-show-successful-but-are-not-being-shown)。

### 如何处理不活跃设备？

离线或废弃的设备不会接收推送通知或发送确认送达事件。这在用户更换或废弃设备时很常见。

要重新吸引不活跃用户：

* 使用**受众活动**向未确认送达的用户重新发送。
* 基于**最后会话**创建[细分](./segmentation)（例如，90天以上不活跃）。
  * 与[重新参与Journey](./journeys-examples#re-engagement-campaign)结合，将他们赢回。
  * 定期针对不活跃用户以清除无法触达的设备。

有关OneSignal如何更新订阅状态的更多详情，请参阅[推送订阅状态何时更新？](./subscriptions#when-do-push-subscription-statuses-update)。

### 为什么显示已确认但在我的设备上没有显示？

确认送达事件意味着设备收到了推送有效载荷。在极少数情况下，通知可能不会显示。

可能的原因：

* **错过通知：** 通过[查找和设置测试订阅](./test-users)向自己发送测试推送来排除这种情况。
* **iOS专注模式：** "请勿打扰"、"睡眠"或其他[专注模式](./ios-focus-modes-and-interruption-levels)会延迟或分组通知。您可能在没有看到的情况下解除了分组通知。
* **抑制显示的应用代码：**
  * [前台生命周期监听器](./mobile-sdk-reference#addforegroundlifecyclelistener-push)或[Notification Service Extension](./service-extensions)中的`event.preventDefault()`会阻止通知显示。
  * 调用[`removeDeliveredNotifications(withIdentifiers:)`](https://developer.apple.com/documentation/usernotifications/unusernotificationcenter/removedeliverednotifications\(withidentifiers:\))或[`removeAllDeliveredNotifications()`](https://developer.apple.com/documentation/usernotifications/unusernotificationcenter/removealldeliverednotifications\(\))会在通知到达后将其删除。
* **推送有效载荷设置：**
  * 确保`priority`设置为高。请参阅[推送优先级](./push#priority)。
  * [`collapse_id`](./push#collapse_id)使用相同ID将旧推送替换为新推送。

***

<Info>
  需要帮助？

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

  请包含以下信息：

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

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