ⓘ 提示
Unity SDK 最低兼容 Unity 2019.3.14 版本,支持平台:Android、iOS
⚠️ 迁移须知
目前 SDK 的全部功能已完成迁移(3.0.0+)? 如何迁移到新 SDK?
请查看《快速迁移指南》。
最新版本(含 Beta 版):
(Android ONLY)
2.将上述文件通过 Assets → Import Package → Custom Package 添加到项目中
3.将 DataTower/ 目录下的 DTSDK.prefab 预制体拖到需要加载的位置(一般放在第一个场景)
4.配置 SDK
5.拉取依赖
Android
iOS
可以在用户每一次登录时,调用 setAccountId
设置用户的账号 ID, DT 系统将会以账号 ID 作为身份识别 ID,多次调用 setAccountId
将覆盖先前的账号 ID
若您的应用没有账号体系可以不设置
using DataTower.Core;
// 自有用户系统的 id
DTAnalytics.SetAccountId("123456");
异步获取由 SDK 生成的设备标识 DT ID
using DataTower.Core;
DTAnalytics.GetDataTowerId(dt_id =>
{
// ...
});
调用 Track
设置自动上报的埋点事件和事件属性
Dictionary<string, object> properties = Dictionary<string, object>();
properties.Add("test_property_3", false);
properties.Add("test_property_4", 2.3);
DTAnalytics.Track("test_track", properties);
// or 不传属性
DTAnalytics.Track("test_track");
DT 系统支持的用户属性设置类型总览说明如下
操作 | 对应事件名 | 处理规则 |
---|---|---|
覆盖用户属性 | #user_set |
对用户表进行操作,覆盖用户的原有属性值,如果之前不存在该用户属性,则会新建该用户属性,类型与覆盖操作传入属性的类型一致 |
初始化用户属性 | #user_set_once |
对用户表进行操作,初始化用户属性,如果该属性已有值存在,系统忽略本次操作 |
累加用户属性 | #user_add |
对用户表进行操作,对数值型的用户属性做累加计算,如果该属性还未被设置,则会赋值 0 后再进行计算,可传入负值等同于相减操作 |
清空用户属性值 | #user_unset |
对用户表进行操作,清空用户属性的属性值,即设置成 NULL,如果被清空的属性不存在也不会新建该属性 |
追加列表型用户属性的元素 | #user_append |
对用户表进行操作,对列表类型的用户属性追加元素,如果被追加的列表属性不存在,系统将自动生成并进行追加 |
追加并去重列表类型用户属性的元素 | #user_uniq_append |
对用户表进行操作,对列表类型的用户属性值追加元素,并会进行一次全列表去重(去重保证前后原有的元素顺序不变),如果被追加的列表属性不存在,系统将自动生成并进行追加再去重 |
对于一般的用户属性,您可以调用 userSet
来进行设置,使用该接口上传的属性将会覆盖原有的属性值,如果之前不存在该用户属性,则会新建该用户属性,类型与覆盖操作传入属性的类型一致
// 此时username为dt_name
DTAnalytics.UserSet(new Dictionary<string, object>(){{"user_name", "dt_name"}});
// 此时username为dt_name2
DTAnalytics.UserSet(new Dictionary<string, object>(){{"user_name", "dt_name2"}});
如果您要上传的用户属性只要设置一次,则可以调用 userSetOnce
来进行设置,当该属性之前已经有值的时候,将会忽略这条信息
// 此时username为dt_name
DTAnalytics.UserSetOnce(new Dictionary<string, object>(){{"user_name", "dt_name"}});
// 此时username仍为dt_name
DTAnalytics.UserSetOnce(new Dictionary<string, object>(){{"user_name", "dt_name2"}});
当您要上传数值型的属性时,您可以调用 userAdd
来对该属性进行累加操作,如果该属性还未被设置,则会赋值 0 后再进行计算,可传入负值,等同于相减操作
// 此时"usermoney"为 6
DTAnalytics.UserAdd(new Dictionary<string, object>(){{"usermoney", 6}});
// 此时"usermoney"为 12
DTAnalytics.UserAdd(new Dictionary<string, object>(){{"usermoney", 6}});
当您要清空用户的用户属性值时,您可以调用 userUnset
来对指定属性进行清空操作,如果该属性还未创建,则 userUnset
不会创建该属性
// 清空用户属性
DTAnalytics.UserUnset("user_password");
如果您要删除某个用户,可以调用 UserDelete
将这名用户删除,您将无法再查询该名用户的用户属性,但该用户产生的事件仍然可以被查询到。
DTAnalytics.UserDelete();
您可以调用 userAppend
对列表类型的用户数据追加元素。
var dictionary = new Dictionary<string, object>();
var lst = new List<string>();
lst.Add("english");
dictionary.Add("course", lst);
DTAnalytics.UserAppend(dictionary);
您可以调用 userUniqAppend
对列表类型的用户数据追加唯一元素。调用 userUniqAppend
接口会对追加的用户属性进行去重, userAppend
接口不做去重,用户属性可存在重复。
var dictionary = new Dictionary<string, object>();
var lst = new List<string>();
lst.Add("english");
lst.Add("math");
dictionary.Add("course", lst);
DTAnalytics.UserUniqAppend(dictionary);
// 上报 广告开始加载事件
void ReportLoadBegin(string id, AdType type, AdPlatform platform, string seq,
Dictionary<string, object> properties = null,
AdMediation mediation = AdMediation.**IDLE**,
string mediationId = "")
// 上报 广告结束加载
void ReportLoadEnd(string id, AdType type, AdPlatform platform, long duration, bool result,
string seq, int errorCode = 0, string errorMessage = "", Dictionary<string, object> properties = null,
AdMediation mediation = AdMediation.**IDLE**,
string mediationId = "")
// 上报 广告展示请求
void ReportToShow(string id, AdType type, AdPlatform platform, string location, string seq,
string entrance = "", Dictionary<string, object> properties = null,
AdMediation mediation = AdMediation.**IDLE**,
string mediationId = "")
// 上报广告展示事件,在展示广告时调用
void ReportShow(string id, AdType type, AdPlatform platform, string location, string seq,
string entrance = "", Dictionary<string, object> properties = null,
AdMediation mediation = AdMediation.**IDLE**,
string mediationId = "")
// 上报广告展示事件,在展示广告时调用
void ReportClick(string id, AdType type, AdPlatform platform, string location, string seq,
string entrance = "", Dictionary<string, object> properties = null,
AdMediation mediation = AdMediation.**IDLE**,
string mediationId = "")
// 上报 广告关闭
void ReportClose(string id, AdType type, AdPlatform platform, string location, string seq,
string entrance = "", Dictionary<string, object> properties = null,
AdMediation mediation = AdMediation.**IDLE**,
string mediationId = "")
// 上报 激励广告已获得奖励
void ReportRewarded(string id, AdType type, AdPlatform platform, string location, string seq,
string entrance = "", Dictionary<string, object> properties = null,
AdMediation mediation = AdMediation.**IDLE**,
string mediationId = "")
// 上报广告收益转化事件,在点击广告时调用(#ad_conversion_source = by_click)
void ReportConversionByClick(String id,AdType type, AdPlatform platform, String location, String seq, String entrance = "" properties: Dictionary<string, object> = null,
AdMediation mediation = AdMediation.**IDLE**,
string mediationId = "")
// 上报广告收益转化事件,在点击广告后跳出App时调用(#ad_conversion_source = by_left_app)
void ReportConversionByLeftApp(String id,AdType type, AdPlatform platform, String location, String seq, String entrance = "" properties: Dictionary<string, object> = null,
AdMediation mediation = AdMediation.**IDLE**,
string mediationId = "")
// 上报广告收益转化事件,在获得广告激励时调用(#ad_conversion_source = by_rewarded)
void ReportConversionByRewarded(String id,AdType type, AdPlatform platform, String location, String seq, String entrance = "" properties: Dictionary<string, object> = null,
AdMediation mediation = AdMediation.**IDLE**,
string mediationId = "")
// 上报广告展示价值事件,在广告SDK回调时调用
fun reportPaid(string id, AdType type, AdPlatform platform, string location, string seq,
string value, string currency, string precision, string entrance = "",
Dictionary<string, object> properties = null,
AdMediation mediation = AdMediation.**IDLE**,
string mediationId = "")
fun reportPaid(string id, AdType type, string platform, string adgroupName, string adgroupType,
string location, string seq,
AdMediation mediation, string mediationId, string value, string currency, string precision, string country,
string entrance = "", Dictionary<string, object> properties = null)
fun reportPaid(string id, AdType type, AdPlatform platform, string location, string seq,
AdMediation mediation, string mediationId, string value, string precision, string country,
Dictionary<string, object> properties = null)
// 上报离开app事件,在点击广告链接,离开当前app(页面)时调用
fun reportLeftApp(string id, AdType type, AdPlatform platform, string location, string seq,
string entrance = "", Dictionary<string, object> properties = null,
AdMediation mediation = AdMediation.**IDLE**,
string mediationId = "")
参数名 | 类型 | 是否必传 | 说明 |
---|---|---|---|
seq | String | 是 | 广告系列事件的标识 |
id | String | 是 | 具体广告 ID |
type | AdType | 是 | UNKNOWN = -1 // 未知 BANNER = 0 //横幅 INTERSTITIAL = 1 //插屏 NATIVE = 2 //原生 REWARDED = 3 //激励 REWARDED_INTERSTITIAL = 4 //插屏激励 APP_OPEN = 5 //开屏广告 |
platform | AdPlatform | 是 | UNDISCLOSED = -2 // 未授权 UNKNOWN = -1 // 未知 ADMOB = 0 MOPUB = 1 ADCOLONY = 2 APPLOVIN = 3 CHARTBOOST = 4 FACEBOOK = 5 INMOBI = 6 IRONSOURCE = 7 PANGLE = 8 SNAP_AUDIENCE_NETWORK = 9 TAPJOY = 10 UNITY_ADS = 11 VERIZON_MEDIA = 12 VUNGLE = 13 ADX = 14 COMBO = 15 BIGO = 16 HISAVANA = 17 APPLOVIN_EXCHANGE = 18 MINTEGRAL = 19 LIFTOFF = 20 A4G = 21 GOOGLE_AD_MANAGER = 22 FYBER = 23 MAIO = 24 CRITEO = 25 MYTARGET = 26 OGURY = 27 APPNEXT = 28 KIDOZ = 29 SMAATO = 30 START_IO = 31 VERVE = 32 LOVINJOY_ADS = 33 YANDEX = 34 REKLAMUP = 35 |
mediation | AdMediation | 否 | 如果不使用聚合广告平台,请传入-1MOPUB = 0 MAX = 1 HISAVANA = 2 COMBO = 3TOPON = 4TRADPLUS = 5TOBID = 6 |
mediationId | String | 否 | 聚合平台广告单元 ID |
entrance | String | 否 | 广告展示入口 |
result | Boolean | 是 | 广告加载结果,true 为广告加载成功 |
duration | Long | 是 | 广告加载时长 |
location | String | 是 | 广告位置,通常为在广告平台配置的位置值 |
errorCode | Int | 否 | 失败码,值为应用接入的对应的广告平台给出的错误码 |
errorMessage | String | 否 | 失败信息,应用接入的对应的广告平台给出的错误信息 |
value | String | 是 | 广告价值,应用接入的对应的广告平台给出的广告价值信息 |
currency | String | 是 | 广告价值对应的货币单位,请传入 USD |
precision | String | 是 | 精确度,广告价值所对应的精确度 |
country | String | 是 | 广告展示所在的国家/地区信息 |
properties | Dictionary | 否 | 自定义属性* |
Admob 激励广告的过程作为演示()
/*
* 一次展示激励广告的过程
*/
AdmobSdkCallbacks.Rewarded.OnAdDisplayedEvent += OnRewardedVideoShownEvent;
AdmobSdkCallbacks.Rewarded.OnAdClickedEvent += OnRewardedVideoClickedEvent;
AdmobSdkCallbacks.Rewarded.OnAdRevenuePaidEvent += OnRewardedAdRevenuePaidEvent;
AdmobSdkCallbacks.Rewarded.OnAdHiddenEvent += OnRewardedVideoClosedEvent;
AdmobSdkCallbacks.Rewarded.OnAdDisplayFailedEvent += OnRewardedVideoFailedToPlayEvent;
AdmobSdkCallbacks.Rewarded.OnAdReceivedRewardEvent += OnRewardedVideoReceivedRewardEvent;
// 广告位,比如这页面是主页
string location = "main"
// MAX 广告单元
string adUnitId = "3940256099942544/1033173712"
// 整个过程的行为系列标识, 这里自行生成一个随机字符串
string seq = UUID()
// 开始加载广告
loadInterstitialAd(adUnitId);
// 展示广告
showInterstitialAd()
......
// 广告回调
// 广告展示成功
private void OnRewardedVideoShownEvent(string adUnitId, AdInfo adInfo){
DTAdReport.ReportShow(adUnitId, AdType.REWARDED, AdPlatform.ADMOB, location, seq)
}
private void OnRewardedVideoFailedToPlayEvent(string adUnitId,ErrorInfo error, AdInfo adInfo){
}
// 广告被点击
private void OnRewardedVideoClickedEvent(string adUnitId, AdInfo adInfo){
DTAdReport.ReportConversionByClick(adUnitId, AdType.REWARDED, AdPlatform.ADMOB, location, seq)
}
private void OnRewardedVideoClosedEvent(string adUnitId, AdInfo adInfo){
}
// 对于激励广告,会有获得激励回调
private void OnRewardedVideoReceivedRewardEvent(string adUnitId, Reward reward, AdInfo adInfo){
DTAdReport.ReportConversionByRewared(adUnitId), AdType.REWARDED, AdPlatform.ADMOB, location, seq)
}
场景一:聚合广告平台
由于聚合广告平台展示广告的时候,没有返回具体是哪个广告平台的广告,所以需要在回调中判断,如 OnRewardedVideoShownEvent 回调
// 聚合广告平台一般会返回广告相关的信息 AdInfo
private void OnRewardedVideoShownEvent(ad: AdInfo){
// 需自行实现 getAdPlatform() 、getAdUnit()方法
val adPlatform = getAdPlatform(ad)
val adUnit = getAdUnit(ad)
// 4. 广告展示成功
DTAdReport.reportShow(adUnit, AdType.INTERSTITIAL,adPlatform,location, seq)
}
其他回调类似
如果你的产品具备内购变现(IAP)功能,DT SDK 已经预置了一些常用的事件接口。在产品的内购变现相关场景中,你可以调用相应的接口。一旦调用了这些接口成功,您可以在我们的后台实时查看内购变现全链路的表现数据。
// 整个过程的行为系列标识, 这里自行生成一个随机字符串
string seq = UUID()
// 上报购买成功事件,购买成功的时候上报 (Android)
DTIAPReport.ReportPurchaseSuccessAndroid(order, "sku123", 3.32, "rmb", new Dictionary());
// 上报购买成功事件,购买成功的时候上报 (iOS)
DTIAPReport.ReportPurchaseSuccessIos(order, "sku123", 3.32, "rmb", seq, "user");
参数名 | 类型 | 是否必传 | 说明 |
---|---|---|---|
seq | string | 是 | 购买行为系列事件的标识 |
placement | string | 是 | 购买行为发生所在的位置,可为空 |
currency | string | 是 | 购买所用的货币单位,与 price 共同决定购买所需的价格 |
price | Double | 是 | 购买所需的价格 |
sku | string | 是 | 购买商品 id |
order | string | 是 | 购买订单 |
properties | Dictionary | 否 | 自定义属性* |
如果你的产品具备内购变现(IAS)功能,DT SDK 已经预置了一些常用的事件接口。在产品的订阅变现相关场景中,你可以调用相应的接口。一旦调用了这些接口成功,您可以在我们的后台实时查看订阅变现全链路的表现数据。
// 整个过程的行为系列标识, 这里自行生成一个随机字符串
var seq = UUID();
// 订阅成功事件上报,订阅成功时上报 (Android)
DTIASReport.ReportSubscribeSuccessAndroid(originalOrderId, orderId, sku, price, currency, properties);
// 订阅成功事件上报,订阅成功时上报 (iOS)
DTIASReport.ReportSubscribeSuccessIos(seq, placement, sku, orderId, originalOrderId, price, currency, entrance);
参数名 | 类型 | 是否必传 | 说明 |
---|---|---|---|
seq | string | 是 | 订阅行为系列事件的标识 |
entrance | string | 是 | 订阅行为入口 |
placement | string | 是 | 订阅行为发生所在的位置 |
currency | string | 是 | 订阅所用的货币单位,与 price 共同决定订阅所需的价格 |
price | string | 是 | 订阅所需的价格 |
sku | string | 是 | 订阅商品 id |
orderId | string | 是 | 订阅订单 |
originalOrderId | string | 是 | 订阅原始订单 id |
properties | Dictionary | 否 | 自定义属性* |
DT 平台提供两种方式进行三方归因集成
如果您需要在 DT 系统中接入 AppsFlyer 归因数据,则需要在 AppsFlyer SDK 初始化完成后,调用 SetAppsFlyerId
接口设置 AppsFlyer ID,DT 系统将用于关联用户的归因信息
// 需要通过 AppsFlyer SDK 获取 appsFlyer_id
DTAnalytics.SetAppsFlyerId("appsFlyer_id");
如果您需要在 DT 系统中接入 Kochava 归因数据,则需要在 Kochava SDK 初始化完成后,调用 setKochavaId
接口设置 Kochava ID,DT 系统将用于关联用户的归因信息。
// 需要通过 Kochava SDK 获取 kochava_id
DTAnalytics.SetKochavaId("kochava_id");
如果您需要在 DT 系统中接入 Adjust 归因数据,则需要在 Adjust SDK 初始化完成后,调用 setAdjustId
接口设置 Adjust ID,DT 系统将用于关联用户的归因信息
// 需要通过 Adjust SDK 获取 adjust_id
DTAnalytics.SetAdjustId("adjust_id");
如果您需要在 DT 系统中接入 Tenjin 归因数据,则需要在 Tenjin SDK 初始化完成后,调用 setTenjinId
接口设置 Tenjin ID,DT 系统将用于关联用户的归因信息。
// 需要通过 Tenjin SDK 获取 Tenjin_id
DTAnalytics.SetTenjinId("tenjin_id");
如果您需要记录某个事件的持续时长,可以调用 DTAnalyticsUtils
来开始计时。
在事件开始时,调用 TrackTimerStart
并不会真正发送事件;在事件结束时调用 TrackTimerEnd
,SDK 会上报 "event" 事件,并自动在"event" 事件属性中加入 #duration
这一属性来表示记录的事件持续时长。多次调用 TrackTimerStart
\ TrackTimerPause
时,事件 "event" 的开始时间\暂停时间以最后一次调用时为准。多次调用 TrackTimerEnd
\ TrackTimerResume
时,事件 "event" 的结束时间\恢复时间以最先一次调用时为准
// 开始事件计时
DTAnalyticsUtils.TrackTimerStart("event");
// 如果需要暂停事件计时
DTAnalyticsUtils.TrackTimerPause("event")
// 如果需要恢事件计时
DTAnalyticsUtils.TrackTimerResume("event")
// 结束事件计时
DTAnalyticsUtils.TrackTimerEnd("event")
// 可以自定义属性
DTAnalyticsUtils.TrackTimerEnd("event", new Dictionary<string, object>(){{"usermoney", 6}} )
如果需要在 Firebase 使用 DT 系统二次加工的用户数据,则需要调用 SetFirebaseAppInstanceId
设置 Firebase 的 app_instance_id,根据 app_instance_id,用户可以给 firebase 上报自定义的用户数据
// 需要先获取Firebase 的 app_instance_id
DTAnalytics.SetFirebaseAppInstanceId("app_instance_id");
如需为所有事件添加属性,可以使用公共属性接口进行设置。
静态公共属性会使用持久化存储,应用退出再开启时,原先设置的值会保持不变。
Dictionary<string, object> staticProps = new() {
{"key", "value"}
};
// 设置
DTAnalytics.SetStaticCommonProperties(staticProps);
// 清除
DTAnalytics.ClearStaticCommonProperties();
动态公共属性会在调用相关事件上报接口时动态地进行公共属性的获取,应用重启后需重新设置。
Dictionary<string, object> dynamicProps = new() {
{"key", "value"}
};
// 设置
DTAnalytics.SetDynamicCommonProperties(() => dynamicProps);
// Track 时会调用动态公共属性的函数来获取公共属性,并进行上报
DTAnalytics.Track("simple_event")
// 清除
DTAnalytics.ClearDynamicCommonProperties();
SDK默认情况下会有一些自动采集的行为,包括预置事件和用户事件
自动采集事件 | 时机 |
---|---|
#app_install(app安装) | App 首次启动,调用 DT.initSDK() 时 |
#session_start(app打开 | App 启动,调用 DT.initSDK() 时、App 从后台切换到前台时(对应 resume) |
#session_end(app关闭) | App 从前台切换到后台时(对应 pause) |
在某些场景下,您可能不希望有任何预置事件的上报,SDK 提供了接口来实现对预置事件的采集与上报的控制。
// 禁用预置事件
DTAnalytics.DisableAutoTrack(DTPresetEvent);
// 取消禁用
DTAnalytics.EnableAutoTrack(DTPresetEvent);
需传入枚举类型 PresetEvent,支持的预置事件。默认为不禁用:
用户事件类型 | 自动上报说明 |
---|---|
user_set | 在每次初始化时,自动上报,用于更新用户最新的属性(#latest_xxx),当最新值未发生变化时,不会上报 |
user_set_once | 用于记录用户激活时的属性(#active_xxx),仅上报一次,相关属性上报过一次就不再上报 |
当您在使用过程中,不希望上报DT的预置属性时,可通过配置文件的方式实现
特殊说明
以下预置属性不可关闭:
属性 | 说明说明 |
---|---|
#bundle_id | 应用包名,属于DT内置字段 |
#app_id | DT的app_id,上报数据的必备字段 |
#debug | 判断该条数据是否是debug |
#dt_id | 上报数据的必备字段,用于用户识别 |
#acid | 用于用户识别 |
#session_id | 会话事件唯一id,标识回话 |
#sdk_type | 判断SDK类型 |
#sdk_version_name | 判断SDK版本 |
配置方式
Assets/Plugins/Android/DataTowerSdk.androidlib/res/values/dt_disable_preset_properties.xml
示例
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="DTDisPresetProperties">
<!-- Add properties here to disable -->
<item>#os_lang_code</item>
<item>#os_version_name</item>
</string-array>
</resources>
仅在 Editor 下运行起效
调用 API 会对传参进行校验,不通过的调用将会抛出异常(ArgumentException),并提供相关错误信息以帮助 Debug。