进阶指南
一、设置用户ID
SDK 实例默认会使用随机 UUID 作为每个用户的默认访客 ID,该 ID 将会作为用户在未登录状态下身份识别 ID。需要注意的是,访客 ID 在用户重新安装 App 以及更换设备时将会变更。
1.1 设置访客 ID
一般情况下,您不需要自定义访客 ID. 请确保已经理解用户识别规则,再进行访客 ID 的设置。
如果您需要替换访客 ID,则应当在初始化 SDK 结束之后立即进行调用,请勿多次调用,以免产生无用的账号
如果您的 App 对每个用户有自己的访客 ID 管理体系,则您可以调用SetDistinctId 来设置访客 ID:
// 将访客ID设置为Thinker
TDAnalytics.SetDistinctId("Thinker");
如果需要获得当前访客 ID,可以调用 GetDistinctId 获取:
//返回访客ID
String distinctId = TDAnalytics.GetDistinctId();
1.2 设置账号 ID
在用户进行登录时,可调用 login 来设置用户的账号 ID, AE 平台将会以账号 ID 作为身份识别 ID,并且设置的账号 ID 将会在调用 logout 之前一直保留。多次调用 login 将覆盖先前的账号 ID 。
// 用户的登录唯一标识,此数据对应上报数据里的#account_id,此时#account_id的值为TA
TDAnalytics.Login("TA");
该方法不会上传登录事件
1.3 清除账号ID
在用户产生登出行为之后,可调用 Logout 来清除账号 ID,在下次调用 Login 之前,将会以访客 ID 作为身份识别 ID。
TDAnalytics.Logout();
我们推荐您在显性的登出事件时调用 Logout,比如用户产生了注销账号这一行为时才调用,而不需要在关闭 App 时调用。
该方法不会上传登出事件
二 、发送事件
在 SDK 初始化完成之后,您就可以进行数据埋点,收集用户的的行为信息。一般情况下普通事件即可满足业务场景需求,您也可以根据自己的实际业务场景使用首次、可更新等事件。
2.1 普通事件
您可以调用 Track 来上传事件,建议您根据先前梳理的文档来设置事件的属性以及发送事件的条件,此处以用户购买某商品作为范例:
Dictionary<string, object> properties = new Dictionary<string, object>(){
{"product_name", "商品名"}
};
TDAnalytics.Track("product_buy", properties);
2.2 首次事件
首次事件是指针对某个设备或者其他维度的 ID,只会记录一次的事件。例如在一些场景下,您可能希望记录在某个设备上第一次发生的事件,则可以用首次事件来上报数据。
Dictionary<string, object> properties = new Dictionary<string, object>() {
{ "status", 1}
};
TDFirstEventModel firstEvent = new TDFirstEventModel("first_event");
firstEvent.Properties = properties;
TDAnalytics.Track(firstEvent);
如果您希望以设备以外的其他维度来判断是否首次,则可以为首次事件自定义first_check_id:
// 将用户ID设置为首次事件的first_check_id,实现用户首次激活事件的采集
Dictionary<string, object> properties = new Dictionary<string, object>() {
{ "status", 1}
};
TDFirstEventModel firstEvent = new TDFirstEventModel("first_event", "any-user-id");
firstEvent.Properties = properties;
TDAnalytics.Track(firstEvent);
注意:由于在服务端完成对是否首次的校验,首次事件默认会延时 1 小时入库。
2.3 可更新事件
您可以通过可更新事件实现特定场景下需要修改事件数据的需求。可更新事件需要指定标识该事件的 ID,并在创建可更新事件对象时传入。AE 后台将根据事件名和事件 ID 来确定需要更新的数据。
// 示例: 上报可被更新的事件,假设事件名为 UPDATABLE_EVENT
// 上报后事件属性 status 为 3, price 为 100
TDUpdatableEventModel updatableEvent = new TDUpdatableEventModel("UPDATABLE_EVENT", "test_event_id");
updatableEvent.Properties = new Dictionary<string, object>{
{"status", 3},
{"price", 100}
};
TDAnalytics.Track(updatableEvent);
// 上报后事件属性 status 被更新为 5, price 不变
TDUpdatableEventModel updatableEvent_new = new TDUpdatableEventModel("UPDATABLE_EVENT", "test_event_id");
updatableEvent_new.Properties = new Dictionary<string, object>{
{"status", 5}
};
TDAnalytics.Track(updatableEvent_new);
2.4 可重写事件
可重写事件与可更新事件类似,区别在于可重写事件会用最新的数据完全覆盖历史数据,从效果上看相当于删除前一条数据,并入库最新的数据。AE 后台将根据事件名和事件 ID 来确定需要更新的数据。
// 示例: 上报可被重写的事件,假设事件名为 OVERWRITABLE_EVENT
// 上报后事件属性 status 为 3, price 为 100
TDOverwritableEventModel overWritableEvent = new TDOverwritableEventModel("OVERWRITABLE_EVENT", "test_event_id");
overWritableEvent.Properties = new Dictionary<string, object>{
{"status", 3},
{"price", 100}
};
TDAnalytics.Track(overWritableEvent);
// 上报后事件属性 status 被更新为 5, price 属性被删除
TDOverwritableEventModel overWritableEvent_new = new TDOverwritableEventModel("OVERWRITABLE_EVENT", "test_event_id");
overWritableEvent_new.Properties = new Dictionary<string, object>{
{"status", 5}
};
TDAnalytics.Track(overWritableEvent_new);
2.5 公共事件属性
公共事件属性指的就是每个事件都会上传的属性。根据属性更新频率,公共事件属性分为静态公共事件属性和动态公共事件属性。您可以根据具体的业务场景需求,选择不同的公共事件属性设置方法;我们推荐您在发送事件前,先设置公共事件属性。针对同一事件,当公共事件属性、事件自定义属性、预置属性的Key相同时,我们会按照如下优先级进行赋值:自定义属性>动态公共事件属性>静态公共事件属性>预置属性。
2.5.1 静态公共事件属性
静态公共事件属性是低频变化且每个事件都会带有的属性,如用户会员等级。通过setSuperProperties设置静态公共事件属性之后,SDK将会在事件采集时获取设置的公共事件属性作为事件的属性。
Dictionary<string, object> superProperties = new Dictionary<string, object>(){
{"vip_level", 2}
};
TDAnalytics.SetSuperProperties(superProperties);
静态公共事件属性将会被保存到缓存中,无需每次启动 App 时调用。如果该属性已存在,重新设置的属性将会覆盖原有属性值;如果之前不存在该属性,则会新建属性。除了属性设置,我们也提供其他API来操作静态公共事件属性,满足日常的业务需求。
// 清除属性名为 CHANNEL 的公共属性
TDAnalytics.UnsetSuperProperty("CHANNEL");
// 清空所有公共属性
TDAnalytics.ClearSuperProperties();
// 获取所有公共属性
TDAnalytics.GetSuperProperties();
2.5.2 动态公共事件属性
动态公共事件属性是高频变化且每个事件都会带有的属性,如用户的金币数量。设置动态公共属性,需要先新建动态公共属性类并实现 TDDynamicSuperPropertiesHandler 接口,复写 public Dictionary<string, object> GetDynamicSuperProperties() 方法,该方法的返回值即是需要设置的动态公共属性,然后调用 SetDynamicSuperProperties 传入动态公共属性对象,样例如下:
// 1.定义动态公共属性实现,此例为设置金币动态变化的示例
public class DynamicProp : TDDynamicSuperPropertiesHandler
{
int coin = 0;
public Dictionary<string, object> GetDynamicSuperProperties()
{
coin++;
return new Dictionary<string, object>() {
{"coin",coin}
};
}
}
// 2.设置动态公共属性
TDAnalytics.SetDynamicSuperProperties(new DynamicProp());
2.6 记录事件时长
如果您需要记录某个事件的持续时长,可以调用 TimeEvent 来开始计时。配置您想要计时的事件名称,当您上传该事件时,将会自动在您的事件属性中加入 #duration 这一属性来表示记录的时长,单位为秒。需要注意的是,同一个事件名只能有一个在计时的任务。
//以下示例,完成用户在某个商品页面停留时长的统计
//用户进入商品页面,开始计时
TDAnalytics.TimeEvent("stay_shop");
/**do someting
.......
**/
//用户离开商品页面,计时结束,"stay_shop" 这一事件中将会带有表示事件时长的属性#duration
TDAnalytics.Track("stay_shop");
三、用户属性
AE 平台支持的用户属性设置API有: UserSet、UserSetOnce、UserAdd、UserUnset、UserDelete、UserAppend、UserUniqAppend。
3.1 UserSet
对于一般的用户属性,您可以调用 UserSet 来进行设置,使用该接口上传的属性将会覆盖原有的属性值,如果之前不存在该用户属性,则会新建该用户属性。
//此时user_name为TA
TDAnalytics.UserSet(new Dictionary<string, object>(){
{"user_name", "TA"}
});
//此时user_name为AE
TDAnalytics.UserSet(new Dictionary<string, object>(){
{"user_name", "AE"}
});
3.2 UserSetOnce
如果您要上传的用户属性只要设置一次,则可以调用 UserSetOnce 来进行设置,当该属性之前已经有值的时候,将会忽略这条信息:
//first_payment_time为2018-01-01 01:23:45.678
TDAnalytics.UserSetOnce(new Dictionary<string, object>(){
{"first_payment_time","2018-01-01 01:23:45.678"}
});
//first_payment_time仍然为2018-01-01 01:23:45.678
TDAnalytics.UserSetOnce(new Dictionary<string, object>(){
{"first_payment_time","2018-12-31 01:23:45.678"}
});
3.3 UserAdd
当您要上传数值型的属性时,您可以调用 UserAdd 来对该属性进行累加操作,如果该属性还未被设置,则会赋值 0 后再进行计算,可传入负值,等同于相减操作。
//此时total_revenue为30
TDAnalytics.UserAdd(new Dictionary<string, object>(){
{"total_revenue",30}
});
//此时total_revenue为678
TDAnalytics.UserAdd(new Dictionary<string, object>(){
{"total_revenue",648}
});
设置的属性key为字符串,Value 只允许为数值。
3.4 UserUnset
如果您需要重置用户的某个属性,可以调用 UserUnset 将该用户指定用户属性的值清空,此接口支持传入字符串或者列表类型的参数:
// 删除单个用户属性
TDAnalytics.UserUnset("userPropertyName");
// 删除多个用户属性
List<string> listProps = new List<string>();
listProps.Add("aaa");
listProps.Add("bbb");
listProps.Add("ccc");
TDAnalytics.UserUnset(listProps);
UserUnset: 的传入值为被清空属性的 Key 值。
3.5 UserDelete
如果您要删除某个用户,可以调用 UserDelete 将这名用户删除,您将无法再查询该名用户的用户属性,但该用户产生的事件仍然可以被查询到。
TDAnalytics.UserDelete();
3.6 UserAppend
从 v1.4.0 开始,您可以调用 UserAppend 为 List 类型的用户属性追加元素:
List<string> stringList = new List<string>();
stringList.Add("apple");
stringList.Add("ball");
// 为属性名为user_list 的用户属性追加 2 个元素
TDAnalytics.UserAppend(new Dictionary<string, object>{
{"user_list", stringList }
});
3.7 UserUniqAppend
从 v2.4.0 开始,您可以调用 UserUniqAppend 为 List 类型的用户属性进行去重追加元素。调用 UserUniqAppend 接口会对追加的用户属性进行去重, UserAppend 接口不做去重,用户属性可存在重复。
//此时user_list的属性值为["apple","ball"]
List<string> stringList = new List<string>();
stringList.Add("apple");
stringList.Add("ball");
TDAnalytics.UserAppend(new Dictionary<string, object>{
{"user_list", stringList}
});
List<string> stringList1 = new List<string>();
stringList1.Add("apple");
stringList1.Add("cube");
//此时user_list的属性值为["apple","apple","ball","cube"]
TDAnalytics.UserAppend(new Dictionary<string, object>{
{"user_list", stringList1}
});
//此时user_list的属性值为["apple","ball","cube"]
TDAnalytics.UserUniqAppend(new Dictionary<string, object>{
{"user_list", stringList1}
});
四、加密功能
从 v2.4.0 版本开始,SDK 支持使用AES+RSA加密数据。数据加密功能需要客户端和服务端配合完成,具体使用方法请咨询客户成功人员。
调用 TDConfig 的 EnableEncrypt 方法,传入公钥和默认版本号。
TDConfig tdConfig = new TDConfig(appId, serverUrl);
// 开启加密传输(仅支持iOS/Android),设置默认版本号、公钥
tdConfig.EnableEncrypt("YOUR_ENCRYPT_PUBLIC_KEY", 1);
TDAnalytics.Init(tdConfig);
五、其他功能
5.1 获取设备ID
您可以通过调用 GetDeviceId 来获取设备 ID:
TDAnalytics.GetDeviceId();
// 以设备ID作为访客ID
// TDAnalytics.SetDistinctId(TDAnalytics.GetDeviceId());
5.2 设置默认时区
默认情况下,SDK 默认会使用接口调用时的本机时间作为事件发生时间上报。您也可以通过设置默认时区接口,指定默认的时区,这样所有的事件都将按照您设置的时区来对齐事件时间:
TDConfig tdConfig = new TDConfig(appId, serverUrl);
tdConfig.timeZone = TDTimeZone.UTC;
TDAnalytics.Init(tdConfig);
用指定时区对齐事件时间,会丢掉设备本机时区信息。如果需要保留设备本机时区信息,目前需要您自己为事件添加相关属性。
5.3 校准时间
SDK 默认会使用本机时间作为事件发生时间上报,如果用户手动修改设备时间会影响到您的业务分析,此时可以通过校准时间操作保证事件发生时间的准确性。我们提供时间戳、NTP两种时间校准方式。
- 您可以使用从服务端获取的当前时间戳对 SDK 的时间进行校准。此后,所有未指定时间的调用,包括事件数据和用户属性设置操作,都会使用校准后的时间作为发生时间。
// 1585633785954 为当前 unix 时间戳,单位为毫秒,对应北京时间 2020-03-31 13:49:45
TDAnalytics.CalibrateTime(1585633785954);
- 您也可以设置NTP服务器地址,之后 SDK 会尝试从传入的 NTP 服务地址中获取当前时间,并对 SDK 时间进行校准。如果在默认的超时时间(3 秒)之内,未获取正确的返回结果,后续将使用本地时间上报数据。
// 使用苹果公司 NTP 服务对时间进行校准
TDAnalytics.CalibrateTimeWithNtp("time.apple.com");
1、使用 NTP 服务进行时间校准存在一定的不确定性,建议您优先考虑用时间戳校准的方式
2、您需要谨慎地选择您的 NTP 服务器地址,以保证网络状况良好的情况下,用户设备可以很快的获取到服务器时间
5.4 立即上报数据
在某些业务场景下,如果您期望数据立即上报到 AE 服务器,可以通过调用Flush接口完成
TDAnalytics.Flush();
5.5 获取国家/地区代码
在某些业务场景下,如果您需要知道用户设备的国家/地区代码,可以通过GetLocalRegion来获取
TDAnalytics.GetLocalRegion();
5.6 支持Lua方式调用
如果需要在Lua文件中直接调用,可以使用封装好的Lua API。点击下载
下载好之后,将TDAnalytics.lua和TDAnalyticsProxy.cs导入到项目中。
使用示例如下:
local config = {
appId = "AppId",
serverUrl = "ServerUrl",
enableLog = true, --是否开启日志,默认为false--
mode = 'debug' --默认为normal--
}
--SDK初始化--
TDAnalytics.init(config);
--如果用户已登录,可以设置用户的账号ID作为身份唯一标识
TDAnalytics.login("TA")
--设置公共事件属性以后,每个事件都会带有公共事件属性
local superProperties = {}
superProperties["channel"] = "ta" -- 字符串
superProperties["age"] = 1 -- 数字
superProperties["isSuccess"] = true -- 布尔
superProperties["birthday"] = os.date("%Y-%m-%d %H:%M:%S") -- 时间
superProperties["object"] = { key="value" } -- 对象
superProperties["object_arr"] = { { key="value" } } -- 对象组
superProperties["arr"] = { "value" } -- 数组
TDAnalytics.setSuperProperties(superProperties) -- 设置公共事件属性
--发送事件
TDAnalytics.track("product_buy", {
product_name="商品名"
});
--设置用户属性
TDAnalytics.userSet({
user_name = "TE"
})
5.7 微信小游戏自动采集事件
针对于微信小游戏平台,目前可支持show事件,hide事件,launch事件自动采集,接入方式如下:
- 下载微信小游戏插件
页面栏 Window->Package Manager-> + -> Add package from git url
PackageManager(git安装URL): https://github.com/wechat-miniprogram/minigame-tuanjie-transform-sdk.git
- 自定义宏
页面栏 Edit -> Project Settings -> Scripting Define Symbols
新增 全局宏参数 TD_WEIXIN_GAME_MODE
点击 Apply 按钮完成设置
- 程序集添加依赖
project窗口布局 ThinkingAnalytics文件夹 -> TDAnalytics(Assembly Definition) -> Assembly Definition References -> + -> WxWasmSDKRuntime
使用实例如下:
// 开启自动采集事件:AppStart 采集 ta_mg_show,AppEnd 采集 ta_mg_hide,AppInstall 采集 ta_mg_launch
TDAnalytics.EnableAutoTrack(TDAutoTrackEventType.AppStart | TDAutoTrackEventType.AppEnd | TDAutoTrackEventType.AppInstall);
5.8 支持IP上报数据
为了预防或解决因DNS劫持导致客户端数据无法正常上报到服务器问题,SDK通过解析ServerUrl获取IP,然后通过IP直接上报数据至服务器。具体开启示例如下:
using ThinkingData.Analytics;
TDConfig config = new TDConfig(appId, serverUrl);
config.EnableDNSService(
TDDNSService.CloudAli,
TDDNSService.CloudFlare,
TDDNSService.CloudGoogle
);
TDAnalytics.Init(config);
枚举 TDDNSService
| 枚举值 | 序号 | 说明 |
|---|---|---|
CloudFlare | 0 | Cloudflare DoH |
CloudAli | 1 | 阿里云 DoH |
CloudGoogle | 2 | Google DoH |
可传入多个服务商,SDK 按传入顺序依次尝试。
5.9 支持sdk错误回调
用于监听 SDK 数据发送或相关操作失败。必须在 Init 之后调用。
调用示例代码如下:
using UnityEngine;
using ThinkingData.Analytics;
public class GameAnalytics : MonoBehaviour, TDErrorCallbackHandler
{
void Start()
{
TDConfig config = new TDConfig(appId, serverUrl);
TDAnalytics.Init(config);
TDAnalytics.RegisterErrorCallback(this);
// 多实例:TDAnalytics.RegisterErrorCallback(this, appId);
}
public void OnSDKErrorCallback(int code, string errorMsg, string ext)
{
Debug.Log("TDAnalytics error, code=" + code
+ ", errorMsg=" + errorMsg
+ ", ext=" + ext);
}
}
- 参数说明
| 参数 | 说明 |
|---|---|
code | 原生 SDK 错误码 |
errorMsg | 错误描述或服务端返回信息 |
ext | 附加上下文,一般为当时的请求数据 |
- 错误码
| 错误码 | 平台 | 说明 |
|---|---|---|
| 1001 | Android | 网络错误 |
| 1002 | Android | 数据库插入失败 |
| 1003 | Android | 数据库异常 |
| 1004 | Android | 数据上报(Flush)失败 |
| 1006 | Android | 网络异常 |
| 10001 | iOS | 网络错误 |
5.10 抖音小游戏自动采集事件
针对于抖音小游戏平台,目前可支持show事件,hide事件,launch事件自动采集,接入方式如下:
- 安装抖音小游戏插件
- 自定义宏
页面栏 Edit -> Project Settings -> Scripting Define Symbols
新增 全局宏参数 TD_DOUYIN_GAME_MODE
点击 Apply 按钮完成设置
使用实例如下:
// 开启自动采集事件:AppStart 采集 ta_mg_show,AppEnd 采集 ta_mg_hide,AppInstall 采集 ta_mg_launch
TDAnalytics.EnableAutoTrack(TDAutoTrackEventType.AppStart | TDAutoTrackEventType.AppEnd | TDAutoTrackEventType.AppInstall);
六、渠道SDK兼容
6.1 腾讯广告
6.1.1 方案简述
在集成了TDAnalytics SDK之后,您无需额外集成腾讯广告SDK。一旦您完成了TDAnalytics的初始化方法,系统会自动触发腾讯广告SDK的初始化。当您上报注册、付费等关键事件时,系统会根据您的配置自动将这些事件信息报送给腾讯广告。
6.1.2 接入流程
- 下载腾讯广告SDK,目前使用的是1.5.4版本,如果换成其他版本的也可以。
- 初始化
TDAnalytics SDK的版本需 >= 3.1.1
TDConfig config = new TDConfig("APPID","SERVER");
config.reportingToTencentSdk = 2; //1 只上报给腾讯 2 上报给腾讯和AE 3 只上报给AE
TDAnalytics.Init(config);
如果需要将数据上报到腾讯,需要在做以下操作:
导出微信小游戏项目之后,将dn-sdk-minigame.js文件导入至项目中,修改game.js引入dn-sdk并完成初始化
import { SDK } from "./dn-sdk-minigame.js";
try {
// 初始化
GameGlobal.dnSDK = new SDK({
user_action_set_id: 123xxxxxx,
secret_key: 'xxxxxxxxxxxxxxxxxxx',
appid: 'xxxxxxxxxxxxx',
});
// 上报启动
GameGlobal.dnSDK.onAppStart();
} catch {
}
- 设置用户ID
- setOpenId
openid一般是调用后端接口异步获取的(获取openid方法),请在获取到 openid 后调用 sdk.setOpenId() 方法设置。openid 和 unionid 只能设置一个,优先设置openid。
获取到openid之后调用
TDAnalytics.login(openid);
- setUnionId
unionid 一般是调用后端接口异步获取的(获取unionid方法),请在获取到 unionid 后调用 sdk.setUnionId() 方法设置。没有openid才需使用此方法设置unionid。
获取到unionid之后调用
TDAnalytics.setDistinctId(unionid);
- 上报行为
Dictionary<string, object> properties = new Dictionary<string, object>(){{"product_name", "商品名"}};
TDAnalytics.Track("product_buy", properties);
如果是以下特定事件,需要上报指定的事件名称
| 事件 | 事件名 | 事件属性(需要包含其中的key) |
小游戏启动 | START_APP | 无 |
付费 | PURCHASE | { value: 600 } |
注册 | REGISTER | |
沉默唤起 | RE_ACTIVE | { backFlowDay: 30 } |
收藏小游戏 | ADD_TO_WISHLIST | { type: 'default', } |
分享小游戏 | SHARE | { target: 'APP_MESSAGE' } |
创建角色 | CREATE_ROL | { name: 'SuperMan' } |
完成新手指引 | TUTORIAL_FINISH | 无 |
游戏等级提升 | UPDATE_LEVEL | { level: 2, power: 85, } |
浏览商城页面 | VIEW_CONTENT | { // 关键场景访问:商城 item: 'Mall', } |
浏览游戏活动 | VIEW_CONTENT | { // 关键场景访问:活动 item: 'Activity', } |
比如上报游戏等级提升事件
Dictionary<string, object> properties = new Dictionary<string, object>();
properties["level"] = 2;
properties["power"] = 85;
2TDAnalytics.Track("product_buy", properties);

