> ## 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自定义结果跟踪推送通知和应用内消息产生的用户操作和收入。自定义归因并通过跨平台的灵活结果类型测量参与度。

<Warning>
  **自定义结果正在被弃用。** 它已被[转化指标](./conversion-metrics)取代，后者提供跨推送、电子邮件、短信、应用内消息和 RCS 的跨渠道最后接触归因。如果您是首次设置转化追踪，请改用[转化指标](./conversion-metrics)。

  现有自定义结果数据仍可作为历史数据访问。
</Warning>

OneSignal自定义结果允许您跟踪由推送通知和应用内消息产生的有意义用户操作。这些操作——如购买、注册或应用事件——可以通过计数、总和和唯一指标进行跟踪，让您深入了解消息活动的影响。

<Info> 自定义结果在**专业版**和**企业版**计划中可用。了解更多关于我们的[定价](https://onesignal.com/pricing)。 </Info>

***

## 结果类型和SDK方法

您可以通过在用户完成特定操作时添加一行代码来触发结果（例如，点击"添加到购物车"或"升级"）。

| 结果类型      |                               移动SDK方法                               |                           Web SDK方法                          | 描述                                              |
| --------- | :-----------------------------------------------------------------: | :----------------------------------------------------------: | ----------------------------------------------- |
| **标准计数**  |          [`addOutcome`](./mobile-sdk-reference#addoutcome)          |       [`sendOutcome`](./web-sdk-reference#sendoutcome)       | 每次调用时将计数增加1。不跟踪值。                               |
| **值（总和）** | [`addOutcomeWithValue`](./mobile-sdk-reference#addoutcomewithvalue) |       [`sendOutcome`](./web-sdk-reference#sendoutcome)       | 将计数增加1，总和增加指定的数值。对收入跟踪很有用。                      |
| **唯一计数**  |    [`addUniqueOutcome`](./mobile-sdk-reference#adduniqueoutcome)    | [`sendUniqueOutcome`](./web-sdk-reference#senduniqueoutcome) | 将计数增加1，每个归因窗口只计算一次。最适合二元用户操作，如"开始滑动会话"或"点击CTA"。 |

<Info> 如果离线，结果事件会在本地缓存，并在下次OneSignal初始化时重新尝试。 </Info>

***

## 计数与总和

结果支持两个关键指标：

| 指标     | 描述                    |
| ------ | --------------------- |
| **计数** | 结果事件被触发的次数            |
| **总和** | 与结果一起发送的所有数值的总计（如果适用） |

带值的结果总是四舍五入到最接近的整数。

**示例**：跟踪购买产生的收入：

<CodeGroup>
  ```java java theme={null}
  // 应用中按下"购买"按钮
     ...
     OneSignal.Session.addOutcomeWithValue("Purchase", 18.76);
  ```

  ```objectivec objectivec theme={null}
  // 应用中按下"购买"按钮
     ...
     [OneSignal.Session addOutcomeWithValue:@"Purchase" value:18.76]
  ```

  ```javascript javascript theme={null}
  //网站上按下购买按钮
  OneSignal.Session.addOutcomeWithValue("Purchase", 20.2);
  ```

  ```javascript Javascript(Web SDK) theme={null}
  //网站上按下购买按钮
  OneSignal.Session.sendOutcome("Purchase", 20.20);
  ```

  ```swift Swift theme={null}
  let value = "20.20"//您提供值
  OneSignal.Session.addOutcome(withValue: "Purchase", value: NSNumber(value:value), onSuccess: {outcomeSent in
    print("结果已发送: \(outcomeSent!.name) 随机值: \(value)" )
  })
  ```

  ```csharp Unity(C#) theme={null}
  //发送结果
  OneSignal.Session.AddOutcome("outcomeName");

  //发送唯一结果
  OneSignal.Session.AddUniqueOutcome("uniqueOutcomeName");

  //发送带浮点值的结果
  OneSignal.Session.AddOutcomeWithValue("outcomeWithVal", 4.2f);
  ```
</CodeGroup>

***

## 用例

### 电子商务网站

在线商店可以使用OneSignal推送通知将用户引导回放弃的购物车、闪购、促销等。通过**结果**，店主现在可以轻松地将推送通知与用户操作（如添加到购物车、购买或兑换优惠券）关联起来。对于购买，结果不仅仅是简单的计数，还可以跟踪购买金额。这使网站所有者可以轻松查看单个推送产生的收入总和。

<CodeGroup>
  ```java java theme={null}
  OneSignal.Session.addOutcomeWithValue("Purchase", 18.76);
  ```

  ```objectivec objectivec theme={null}
  [OneSignal.Session addOutcomeWithValue:@"Purchase" value:18.76]
  ```

  ```javascript javascript theme={null}
  OneSignal.Session.addOutcomeWithValue("Purchase", 18.76);
  ```

  ```Text Javascript(Web SDK) theme={null}
  OneSignal.Session.sendOutcome("Purchase", 18.76);
  ```

  ```csharp Unity(C#) theme={null}
  OneSignal.Session.AddOutcomeWithValue("Purchase", 18.76);
  ```
</CodeGroup>

### 社交应用

社交应用可能希望通过推送来重新吸引用户，通知他们匹配或好友请求、新的点赞，或者只是让他们滑动。通过使用**结果**，开发者可以看到推送通知是否导致了用户事件，比如与匹配对象发起聊天或34秒的滑动会话。然后可以使用这些数据来完善通知和定位策略。

在以下示例中，我们想要跟踪用户是否在推送后开始滑动交友资料。由于我们不想将每次滑动都计为转换，我们使用`sendUniqueOutcome`

这个"滑动"结果只会归因一次给触发它的推送。示例：

* 如果用户点击了推送并执行了调用此方法的操作，这将是直接归因。
* 如果用户收到了推送但没有点击它，并在归因窗口内执行了操作，这将是受影响的归因。即使他们后来点击相同的推送并再次执行操作，仍然只会是受影响的。
* 如果用户在归因窗口外执行方法，每个会话将被计为一次未归因。

<CodeGroup>
  ```java Java theme={null}
  OneSignal.Session.addUniqueOutcome("Swipe");
  ```

  ```objectivec Objective-C theme={null}
  [OneSignal.Session addUniqueOutcome:@"Swipe"]
  ```

  ```javascript JavaScript theme={null}
  OneSignal.Session.addUniqueOutcome("my_outcome_event");
  ```

  ```csharp C# theme={null}
  OneSignal.Session.AddUniqueOutcome("swipe");
  ```
</CodeGroup>

### 按语言点击推送

在我们SDK的通知打开/点击监听器方法中，您可以设置结果来增加按其设置语言点击推送的设备数量。这将需要一些原生代码来检测设备的语言，但您可以将该语言传递到结果中，如下所示：

<CodeGroup>
  ```java Java theme={null}
    public void notificationOpened(OSNotificationOpenResult result) {
      String languageCode = Locale.getDefault().getLanguage();
      System.out.println("languageCode " + languageCode);
      OneSignal.Session.addOutcome(languageCode);
    }
  ```

  ```swift Swift theme={null}
  let notificationOpenedBlock: OSHandleNotificationActionBlock = { result in
    // 当用户对收到的通知做出反应时，这个块被调用
    if let languageCode = Locale.current.languageCode {
        print ("languageCode: " + languageCode);
        OneSignal.Session.addOutcome(languageCode);
    }
  }
  ```

  ```javascript JavaScript theme={null}
  var language = navigator.language;
  OneSignal.Session.addOutcome(language);
  ```
</CodeGroup>

### 按操作系统和浏览器点击推送

在我们SDK的通知打开/点击监听器方法中，您可以设置结果来增加特定平台的点击数。对于iOS和Android，这很通用，因为您可以在移动应用的点击处理器中设置`OneSignal.addOutcome("iOS")`或`OneSignal.addOutcome("Android")`，但如果您也想跟踪网络推送平台，可以使用这个示例：

<CodeGroup>
  ```javascript Javascript(Web SDK) theme={null}
  // 示例取自Stackoverflow: https://stackoverflow.com/questions/11219582/how-to-detect-my-browser-version-and-operating-system-using-javascript
  var os = "未知操作系统";
  if (navigator.userAgent.indexOf("Win") != -1) os = "Windows";
  if (navigator.userAgent.indexOf("Mac") != -1) os = "Macintosh";
  if (navigator.userAgent.indexOf("Linux") != -1) os = "Linux";
  if (navigator.userAgent.indexOf("Android") != -1) os = "Android";
  if (navigator.userAgent.indexOf("like Mac") != -1) os = "iOS";
  console.log('您的操作系统: ' + os);

  var browserType = "未知浏览器类型";
  if (navigator.userAgent.indexOf("Safari") != -1) browserType = "Safari";
  if (navigator.userAgent.indexOf("Chrome") != -1) browserType = "Chrome";
  if (navigator.userAgent.indexOf("OPR") != -1) browserType = "Opera";
  if (navigator.userAgent.indexOf("Firefox") != -1) browserType = "Firefox";
  console.log('您的浏览器: ' + browserType);

  OneSignal.push(["addListenerForNotificationOpened", function(data) {
  OneSignal.Session.sendOutcome(os);
  OneSignal.Session.sendOutcome(browserType);
  }]);

  ```
</CodeGroup>

***

## 禁用结果跟踪

在仪表板**设置 > 推送和应用内 > 结果跟踪**中禁用特定结果的跟踪。

从这里，您可以点击**停止跟踪**按钮来选择在仪表板中停止跟踪的结果。一旦您停止跟踪结果，您将看到它们在这里列出，并可以通过点击**开始跟踪**链接再次开始跟踪它们。

***

## 常见问题

### 结果数据存储多长时间？

* 从仪表板发送的通知永远保留其结果数据。
* 通过API发送的通知的结果保留期为30天，之后会被清除。

### 哪些渠道支持自定义结果？

目前自定义结果只能添加到推送和应用内消息的操作中。

通过应用内消息发送的结果将显示为"未归因"，并将在设备上设置格式为`结果名称 : true`的标签。

### 我可以导出结果吗？

您可以将一组结果或所有结果导出为CSV。我们还为[单个通知](/reference/view-message)或[所有通知](/reference/view-outcomes)提供结果的API访问。

### 我可以在自定义结果中将字符串存储为值吗？

不支持这样做。

### 设备离线时会发生什么？

触发结果的数据会排队，一旦设备再次在线就发送到OneSignal。

### 如果用户在点击通知后将应用置于后台，然后返回并触发结果，这算直接归因还是受影响归因？

只要用户在应用后台化后30秒内返回应用，会话仍会被视为原始会话并获得直接归因。

### 新的归因窗口何时生效？

如果您将归因窗口从24小时更改为1小时，那么1小时窗口将在每个设备从全新会话打开应用后按设备生效。这个新会话在应用外超过30秒后创建。

### 为什么会话与其他分析不匹配？

OneSignal只在用户离开应用超过30秒后才计算会话。如果您关闭应用或网站并在30秒内返回，这不会是新会话。

例如，苹果的分析将会话跟踪为应用使用至少两秒的次数。如果应用在后台，稍后再次使用，那会算作另一个会话。

***
