概要:本文主要讲解了通过Unity开发的安卓和iOS应用如何安装AppsFlyer SDK并完成对接。基础的对接工作完成后,您就可以对该应用的激活进行归因,并衡量其应用内事件。
相关文章
下列文档可以帮助您更全面地了解Unity插件对接流程的各个方面:
- Unity插件V6版本接入指南——总体说明
- Unity插件V6版本接入指南—基础SDK对接(本文)
- Unity插件V6版本接入指南——进阶SDK对接
- Unity插件V6版本接入指南——API参考信息
如何在应用中添加插件
注意事项!
AppsFlyer的Unity SDK不支持Unity内置的Build System。
下载AppsFlyer的Unity插件
请从GitHub下载最新版的Unity插件。
安装插件
您可以使用以下任意一种方式进行安装。
默认情况下,AppsFlyer的Unity插件会连带Unity的External Dependency Manager for Unity(外部依赖关系管理器,即EDM4U)一起安装。该管理器可解决Unity插件与项目中其他插件之间的依赖关系冲突,从而简化接入流程。
请按以下步骤安装该插件:
添加appsflyer-unity-plugin.v*.unitypackage,自动导入AppsFlyer插件和EDM4U所需的所有资源。
请按以下步骤在不使用EDM4U的情况下安装该插件:
- 将appsflyer-unity-plugin.v*.unitypackage导入到您的项目中,并取消对EDM4U依赖项的选择。
- 下载所需的Android依赖项并将其添加到Assets/Plugins/Android文件夹中:
- 下载所需的iOS依赖项并将其添加到Assets/Plugins/iOS/AppsFlyer文件夹中:
设置Android
设置所需的Android权限:
请在AndroidManifest.xml
中设置以下权限:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
API级别为31的应用(对应系统为Android 12)需要在AndroidManifest.xml
中添加以下权限,才能读取Android Advertising Identifier(安卓广告标识符):
<uses-permission android:name="com.google.android.gms.permission.AD_ID" />
插件初始化
本节为您讲解Unity插件的安装及初始化流程。
获取dev key
- 该密钥是用来识别账户的唯一标识符。某些情况下存在应用层级的密钥。
- Dev key是必填项。
请按以下步骤获取dev key:
- 从AppsFlyer后台进入配置 > 应用配置 。
- 获取dev key。
插件初始化
请按以下步骤通过prefab对插件进行初始化:
- 进入Assets > AppsFlyer。
- 将AppsFlyerObject.prefab拖动到Scene中。
- 设置以下字段:
设置 说明 Dev key 将上个环节中获取的dev key粘贴到该字段中。 App ID iOS:输入相关的iOS应用ID(不带前缀
id
)。安卓:不填。
获取转化数据 如果应用中接入了AppsFlyer的深度链接,则设为“True”。默认为“False”,即默认不接入深度链接。 Is debug 如需在开发过程中查看调试日志:设置为“true”。
注意:将应用发布到生产环境时,请确保该设置处于禁用状态(即设置为“false”)。
- 进入Assets > AppsFlyer > AppsFlyerObjectScript.cs,使用其他可用API更新其中的代码。
请按以下方式手动接入插件:
创建一个游戏对象(game object)并添加以下初始化代码:
using AppsFlyerSDK;
public class AppsFlyerObjectScript : MonoBehaviour , IAppsFlyerConversionData
{
void Start()
{
/* AppsFlyer.setDebugLog(true); */
AppsFlyer.initSDK("devkey", "appID", this);
AppsFlyer.startSDK();
}
public void onConversionDataSuccess(string conversionData)
{
AppsFlyer.AFLog("onConversionDataSuccess", conversionData);
Dictionary<string, object> conversionDataDictionary = AppsFlyer.CallbackStringToDictionary(conversionData);
// add deferred deeplink logic here
}
public void onConversionDataFail(string error)
{
AppsFlyer.AFLog("onConversionDataFail", error);
}
public void onAppOpenAttribution(string attributionData)
{
AppsFlyer.AFLog("onAppOpenAttribution", attributionData);
Dictionary<string, object> attributionDataDictionary = AppsFlyer.CallbackStringToDictionary(attributionData);
// add direct deeplink logic here
}
public void onAppOpenAttributionFailure(string error)
{
AppsFlyer.AFLog("onAppOpenAttributionFailure", error);
}
}
注意:切勿对该游戏对象调用destroy(销毁)。
记录应用内事件
记录应用内事件可以用来衡量收入、ROI和LTV(生命周期价值)等KPI。
您需要先对应用内事件进行打点,然后才能记录用户事件。发送事件的方式有以下几种:
- 【推荐】从应用侧发送事件(即本文所述方式)。
- 其他方式请参考应用内事件概览。
对于旅游、游戏、电商等垂类应用,您可以参考分垂类的应用内事件推荐列表,这些文档能帮助您判断要记录哪些应用内事件。
应用内事件的名称和参数
发送事件前的准备工作:
- 指定事件的名称和参数。
- 查看相关列表:
- 事件名称和结构推荐列表
- 在
AFInAppEvents
类中的列表。
【推荐】建议使用事件名称和参数,原因如下:
- 命名标准化:AppsFlyer可以自动将事件映射到Facebook、Google和Twitter等SRN。
- 向后兼容性:即使AppsFlyer后台的事件名称或参数有所变化,仍能正常记录事件。应用内事件的设置是向后兼容的。
记录收入
在应用内事件中添加af_revenue
参数后,便可上报收入。
af_revenue
需要以数值填充,允许出现负值。- AppsFlyer通过
af_revenue
参数用统计收入并填充原始数据中的相关字段,以便市场人员在面板中查看收入数据。 - 虽然您也可以使用其他参数发送收入,但是AppsFlyer是无法识别这些收入的。详情请见此文档。
- 收入值中不能带有逗号分隔符、货币符号或文本。
收入值示例:1234.56
推荐做法:详见货币的设置、显示和换算。
设置收入事件的货币代码时需要注意以下几点:
- 默认货币:USD(美元)
- 必须使用3个字符的ISO 4217代码(示例如下)。
- 可通过调用API设置货币代码:
AppsFlyer.setCurrencyCode("ZZZ")
示例 :带有收入的应用内购买事件
假设某个购买事件的订单总额为200.12欧元。如果您想要让该事件的收入显示到面板上,就需要用到以下事件名称和参数:
System.Collections.Generic.Dictionary<string, string> purchaseEvent = new
System.Collections.Generic.Dictionary<string, string> ();
purchaseEvent.Add(AFInAppEvents.CURRENCY, "EUR");
purchaseEvent.Add(AFInAppEvents.REVENUE, "200.12");
purchaseEvent.Add(AFInAppEvents.QUANTITY, "1");
purchaseEvent.Add(AFInAppEvents.CONTENT_TYPE, "category_a",);
AppsFlyer.sendEvent ("af_purchase", purchaseEvent);
记录负收入
您可以使用减号来记录负收入。
- 收入值前面带有减号的收入会记录为负收入。
- 负收入有专用的事件名称,即“cancel_purchase”,便于您在原始数据报告和面板上识别负收入事件。
示例:应用用户收到退款或取消订阅。
System.Collections.Generic.Dictionary<string, string> purchaseEvent = new
System.Collections.Generic.ictionary<string, string> ();
purchaseEvent.Add(AFInAppEvents.CURRENCY, "USD");
purchaseEvent.Add(AFInAppEvents.REVENUE, "-200");
purchaseEvent.Add(AFInAppEvents.QUANTITY, "1");
purchaseEvent.Add(AFInAppEvents.CONTENT_TYPE, "category_a");
AppsFlyer.sendEvent ("cancel_purchase", purchaseEvent);
应用内购验证
该插件可对应用内购进行服务器端验证。
以下是分操作系统的内购验证说明:
#if UNITY_ANDROID && !UNITY_EDITOR
AppsFlyerAndroid.validateAndSendInAppPurchase(
"publicKey",
"signature",
"purchaseData",
"price",
"currency",
null,
this);
#endif
请务必在Apple沙盒环境中调用服务器来测试内购验证:
#if UNITY_IOS && !UNITY_EDITOR
AppsFlyeriOS.validateAndSendInAppPurchase(
"productIdentifier",
"price",
"currency",
"tranactionId",
null,
this);
#endif
方法参数
参数 | 说明 |
---|---|
String publicKey | Google Developer Console的公共密钥 |
String signature |
交易签名;每次购买完成时由Google API返回 |
String purchaseData |
JSON格式的购买产品信息;每次购买完成时由Google API返回 |
String revenue | 上报到AppsFlyer的应用内事件收入 |
String currency | 上报到AppsFlyer的应用内事件货币单位 |
Dictionary<String, String> additionalParameters |
其他的应用内事件参数,这些参数会显示在应用内事件原始数据的event_value字段中 |
参数 | 说明 |
---|---|
String productIdentifier | 产品标识符 |
String price | 上报到AppsFlyer的应用内事件收入 |
String currency | 上报到AppsFlyer的应用内事件货币单位 |
Dictionary<String, String> additionalParameters |
其他的应用内事件参数,这些参数会显示在应用内事件原始数据的event_value字段中 |
注意
调用validateReceipt
会自动生成 af_purchase应用内事件。
因此请勿在验证购买后再次发送购买事件,否则会导致事件重复上报。
设置应用内事件时的注意事项
- 事件名称:最多45个字符
- 事件值:不得超过1000个字符,否则数据会被截断
- 应用内事件(及其他API)可使用非英语字符
- 定价和收入:
- 仅支持数字(可带小数点),例如5或5.2
- 最多精确到小数点后5位,例如5.12345
应用内事件记录示例
您可以通过调用sendEvent
来记录应用内事件,并设置事件名称和值参数。
详情请见应用内事件。
示例:如何记录应用内购买事件
请参考分垂类的富应用内事件指南,其中详尽列出了适用于各个垂类的现成代码片段。
System.Collections.Generic.Dictionary<string, string> purchaseEvent = new
System.Collections.Generic.Dictionary<string, string> ();
purchaseEvent.Add(AFInAppEvents.CURRENCY, "USD");
purchaseEvent.Add(AFInAppEvents.REVENUE, "200");
purchaseEvent.Add(AFInAppEvents.QUANTITY, "2");
purchaseEvent.Add(AFInAppEvents.CONTENT_TYPE, "category_a");
purchaseEvent.Add(AFInAppEvents.CONTENT_ID, "092");
AppsFlyer.sendEvent (AFInAppEvents.PURCHASE, purchaseEvent);
记录离线应用内事件
用户在没有网络连接的情况下也可能会触发应用内事件。 AppsFlyer会把这些事件放到缓存中,等到有网络的时候再进行上报。
- 该插件将事件发送到AppsFlyer服务器并等待响应。
- 如果未收到200响应,则将事件存储在缓存中。
- 收到下一个200响应后,再将缓存的事件重新发送到服务器。
- 如果缓存中包含多个事件,则会将其依次发送到服务器。
注意
缓存中最多可以存储40个事件。
- 仅保存前40个离线事件。
- 在下一个200个响应前、前40个事件后产生的所有事件都会丢失。
- 在原始数据报告中,
- 事件时间 = 设备重新联机后将事件发送到AppsFlyer的时间,
- 而不是事件实际发生的时间。
OneLink深度链接
OneLink是AppsFlyer的多平台归因解决方案,主要功能包括跳转和深度链接 。
设备识别和跳转
OneLink:
- 当用户点击链接时识别设备类型(安卓、iOS、PC端等),然后
- 让用户跳转到与其设备对应的地址,如Google Play、iOS应用商店,第三方商店或网页。
详情请见OneLink跳转指南,其中说明了多平台归因链接的使用方式以及深度链接的基础信息。
深度链接
您可以使用深度链接让现有用户跳转到应用中的具体页面或自定义内容。
使用OneLink实现深度链接需要应用所有者和开发人员共同协作:
- 应用所有者必须在AppsFlyer面板中完成相关操作
- 开发人员必须在应用中完成相关操作
请参阅使用OneLink设置深度链接 。
延迟深度链接
延迟深度链接可以让新用户在首次打开应用时通过深度链接跳转到应用内指定的页面和自定义内容。
标准的深度链接也可以让用户跳转到应用内指定的页面和自定义内容,但前提是他们的设备上已经安装了该应用。
使用OneLink设置延迟深度链接时:
- 开发人员需要在AppsFlyer后台完成相关操作。
- 延迟深度链接和标准深度链接在AppsFlyer后台的设置是相同的。
- 如需通过深度链接让用户在首次打开应用时跳转到自定义内容,必须在应用中添加相应的逻辑。
详情请见延迟深度链接。
获取深度链接数据
每次安装或深层链接事件后,该插件都会提供转化或互动数据。使用此数据来自定义内容或应用程序的编程行为。
如需接收深度链接数据,请确保:
- 添加回调函数
onAppOpenAttribution
(在IAppsFlyerConversionData
类中);由AppsFlyer的插件调用。 - 返回的OneLink/归因链接参数触发应用打开。
- 解析参数值并应用逻辑来触发相关的应用页面。
public void onAppOpenAttribution(string attributionData)
{
AppsFlyer.AFLog("onAppOpenAttribution", attributionData);
Dictionary<string, object> attributionDataDictionary = AppsFlyer.CallbackStringToDictionary(attributionData);
// add direct deeplink logic here
}
详情请见深度链接数据。
获取转化数据
您可以查看每次激活的实时用户归因数据,这些数据可以通过以下方式帮助您提升用户互动:
- 个性化内容
- 让用户进入应用内的特定页面。详情请见本文中的延迟深度链接部分。
获取AppsFlyer转化数据
如需获取AppsFlyer转换数据,请完成以下操作:
- 接入
IAppsFlyerConversionDatabase
。 - 调用
initSDK
方法,将其作为最后一个参数。 - 使用
onConversionDataSuccess
方法实现用户跳转。
onConversionDataSuccess的详情请见API参考信息。
using AppsFlyerSDK;
public class AppsFlyerObjectScript : MonoBehaviour , IAppsFlyerConversionData
{
void Start()
{
/* AppsFlyer.setDebugLog(true); */
AppsFlyer.initSDK("devkey", "appID", this);
AppsFlyer.startSDK();
}
public void onConversionDataSuccess(string conversionData)
{
AppsFlyer.AFLog("onConversionDataSuccess", conversionData);
Dictionary<string, object> conversionDataDictionary = AppsFlyer.CallbackStringToDictionary(conversionData);
// add deferred deeplink logic here
}
public void onConversionDataFail(string error)
{
AppsFlyer.AFLog("onConversionDataFail", error);
}
public void onAppOpenAttribution(string attributionData)
{
AppsFlyer.AFLog("onAppOpenAttribution", attributionData);
Dictionary<string, object> attributionDataDictionary = AppsFlyer.CallbackStringToDictionary(attributionData);
// add direct deeplink logic here
}
public void onAppOpenAttributionFailure(string error)
{
AppsFlyer.AFLog("onAppOpenAttributionFailure", error);
}
}