# Cocos2d-x SDK 使用指南
提示
在接入前, 请先阅读接入前准备。
您可以在 GitHub (opens new window) 获取Cocos2d-x SDK 源码。
Cocos2d-x SDK 支持在iOS、Android平台运行,大小约为 6.4M
最新版本为: v1.1.1
更新时间为: 2021-11-19 下载地址 (opens new window)
# 一、初始化 SDK
# 1.1 集成 SDK
下载 Cocos2d-x SDK (opens new window) 资源文件,解压文件,把ThinkingAnalytics文件夹放入Classes文件夹
CMakeLists.txt
添加如下配置
list(APPEND GAME_SOURCE
Classes/ThinkingAnalytics/Common/TDJSONObject.cpp
)
list(APPEND GAME_HEADER
Classes/ThinkingAnalytics/Common/TDJSONObject.h
Classes/ThinkingAnalytics/Common/ThinkingAnalyticsAPI.h
)
if(ANDROID)
list(APPEND GAME_SOURCE
Classes/ThinkingAnalytics/Android/ThinkingAnalyticsAPI.cpp
)
- 添加Android端配置
- 在proj.android中的app目录下添加libs文件夹,把thinkingsdk.aar放入libs文件夹
- proj.android中app目录下的build.gradle添加如下配置
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar','*.aar'])
}
- 添加iOS端配置
- 使用XCode打开iOS项目,直接拖拽ThinkingAnalytics下面的iOS文件夹放入Classes/ThinkingAnalytics目录下
Build Setting->Other Linker Flags
中的Debug和Release分别添加-all_load
Build Phases->Compile Sources
中的ThinkingAnalytics.mm添加-fobjc-arc
# 1.2 初始化SDK
#include "./ThinkingAnalytics/Common/ThinkingAnalyticsAPI.h"
using namespace thinkingdata;
ThinkingAnalyticsAPI::init(TA_APP_ID, TA_SERVER_URL);
//支持初始化多个APPID实例
ThinkingAnalyticsAPI::init(TA_APP_ID_1, TA_SERVER_URL_1);
或者
// 获取 TDConfig 实例
Config config(TA_APP_ID, TA_SERVER_URL);
// 设置运行模式为 Debug 模式
config.setModel(DEBUG);
// 初始化 SDK
ThinkingAnalyticsAPI::init(config);
或者
注意:由于一些设备默认禁止明文传输,因此强烈建议您使用 HTTPS 格式的接收端地址。
# 二、设置用户 ID
在使用Cocos2d-x SDK 之后,SDK 默认会使用随机 UUID 作为每个用户的访客 ID,该 ID 将会作为用户在未登录状态下身份识别 ID。需要注意的是,默认访客 ID 在用户重新安装游戏以及更换设备时将会变更。
# 2.1 设置访客 ID(可选)
如果您的游戏对每个用户有自己的访客 ID 管理体系,则您可以调用 identify
来设置访客 ID:
ThinkingAnalyticsAPI::identify("cocos2dx_id");
如果需要获得访客 ID,可以调用 getDistinctId
获取:
ThinkingAnalyticsAPI::getDistinctId();
# 2.2 设置与清除账号 ID
在用户进行登录时,可调用 login
来设置用户的账号 ID,在设置完账号 ID 后,将会以账号 ID 作为用户标识 ID,并且设置的账号 ID 将会在调用 logout
之前一直保留:
// 设置账号 ID
ThinkingAnalyticsAPI::login("cocos2dx_user");
// 清除账号 ID
ThinkingAnalyticsAPI::logout();
注意:该方法不会上传用户登录、用户登出等事件。
# 三、上传事件
通过 ThinkingAnalyticsAPI::track()
可以上报事件及其属性。一般情况下,您可能需要上传十几到上百个不同的事件,如果您是第一次使用 TA 后台,我们推荐您先上传几个关键事件。
我们也支持了若干自动采集事件,包括游戏启动、关闭、安装等事件。
# 3.1 上传事件
建议您根据先前梳理的文档来设置事件的属性以及发送信息的条件。事件名称是 string
类型,只能以字母开头,可包含数字,字母和下划线 "_",长度最大为 50 个字符,对字母大小写不敏感。
TDJSONObject eventProperties;
eventProperties.setString("role", "战士");
eventProperties.setNumber("coin",1);
ThinkingAnalyticsAPI::track("thinkingdata",eventProperties);
- 事件属性是
TDJSONObject
类型,其中每个元素代表一个属性; - 事件属性
Key
为属性名称,为string
类型,规定只能以字母开头,包含数字,字母和下划线 "_",长度最大为 50 个字符,对字母大小写不敏感; - 属性值支持四种类型:字符串、数值类、
bool
、List
类型。
# 3.2 设置静态公共属性
对于一些重要的属性,譬如玩家的区服和渠道等,这些属性需要设置在每个事件中,此时您可以将这些属性设置为公共事件属性。公共事件属性指的就是每个事件都会带有的属性,您可以调用 setSuperProperties
来设置公共事件属性,我们推荐您在发送事件前,先设置公共事件属性。
TDJSONObject userProperties;
userProperties.setString("level", "100");
userProperties.setDateTime("dateTime","2020-01-02 10:52:52.290");
ThinkingAnalyticsAPI::setSuperProperties(userProperties);
公共事件属性将会被保存到缓存中,无需每次启动 APP 时调用。如果调用 setSuperProperties
上传了先前已设置过的公共事件属性,则会覆盖之前的属性。如果公共事件属性和 track()
上传的某个属性的 Key
重复,则该事件的属性会覆盖公共事件属性。
如果您需要删除某个公共事件属性,可以调用 unsetSuperProperty()
清除其中一个公共事件属性;如果您想要清空所有公共事件属性,则可以调用 clearSuperProperties()
;如果您想要获取所有公共事件属性,可以调用getSuperProperties
;
// 清除属性名为 CHANNEL 的公共属性
ThinkingAnalyticsAPI::unsetSuperProperty("CHANNEL");
// 清空所有公共属性
ThinkingAnalyticsAPI::clearSuperProperties();
// 获取所有公共属性
ThinkingAnalyticsAPI::getSuperProperties();
# 3.3 设置动态公共属性
在 v1.1.0 版本中,新增了动态公共属性的特性,即公共属性可以上报时获取当时的值,使得诸如会员等级之类的可变公共属性可以被便捷地上报。通过 setDynamicSuperProperties
设置动态公共属性类之后,SDK 将会在事件上报时自动获取属性,并添加到触发的事件中。以下例子是每次上报时将时间加入到事件中,当事件触发时,就会将 dynamicProperties
的返回值加入到事件属性中。
// 设置动态公共属性,在事件上报时动态获取事件发生时刻
TDJSONObject dynamicProperties()
{
TDJSONObject obj;
obj.setNumber("num",1);
return obj;
}
ThinkingAnalyticsAPI::setDynamicSuperProperties(dynamicProperties);
# 3.4 记录事件时长
如果您需要记录某个事件持续时长,您可以调用 timeEvent()
来开始计时,配置您想要计时的事件名称,当您上传该事件时,将会自动在您的事件属性中加入 #duration
这一属性来表示记录的时长,单位为秒。
// 调用 TimeEvent 开启对 TIME_EVENT 事件的计时
ThinkingAnalyticsAPI::timeEvent("TIME_EVENT");
// do some thing...
// 通过 Track 上传 TIME_EVENT 事件时,会在属性中添加 #duration 属性
ThinkingAnalyticsAPI::track("TIME_EVENT");
# 四、用户属性
TA 平台目前支持的用户属性设置接口为 user_set
、user_setOnce
、user_add
、user_unset
、user_delete
、user_append
.
# 4.1 user_set
对于一般的用户属性,您可以调用 user_set
来进行设置,使用该接口上传的属性将会覆盖原有的属性值,如果之前不存在该用户属性,则会新建该用户属性。
TDJSONObject userProperties;
userProperties.setString("role", "战士");
userProperties.setNumber("coin",1);
ThinkingAnalyticsAPI::user_set(userProperties);
与事件属性类似:
- 事件属性是
TDJSONObject
类型,其中每个元素代表一个属性; - 事件属性
Key
为属性名称,为string
类型,规定只能以字母开头,包含数字,字母和下划线 "_",长度最大为 50 个字符,对字母大小写不敏感; - 属性值支持四种类型:字符串、数值类、
bool
、List
类型。
# 4.2 user_setOnce
如果您要上传的用户属性只要设置一次,则可以调用 user_setOnce
来进行设置,当该属性之前已经有值的时候,将会忽略这条信息:
TDJSONObject userProperties;
userProperties.setString("role", "战士");
userProperties.setNumber("coin",1);
ThinkingAnalyticsAPI::user_setOnce(userProperties);
注意:
user_setOnce
设置的用户属性类型及限制条件与user_set
一致。
# 4.3 user_add
当您要上传数值型的属性时,您可以调用 user_add
来对该属性进行累加操作,如果该属性还未被设置,则会赋值 0
后再进行计算,可传入负值,等同于相减操作。
TDJSONObject userProperties;
userProperties.setNumber("coin",1);
ThinkingAnalyticsAPI::user_add(userProperties);
注意:
user_add
中的属性类型以及Key
值的限制与user_set
一致,但Value
只允许上报数值类型属性。
# 4.4 user_unset
如果您需要重置用户的某个属性,可以调用 user_unset
将该用户指定用户属性的值清空,此接口支持传入字符串或者列表类型的参数:
ThinkingAnalyticsAPI::user_unset("coin");
# 4.5 user_delete
如果您要删除某个用户,可以调用 user_delete
将这名用户删除,您将无法再查询该名用户的用户属性,但该用户产生的事件仍然可以被查询到。
ThinkingAnalyticsAPI::user_delete();
# 4.6 user_append
您可以调用 UserAppend
为 List
类型的用户属性追加元素:
TDJSONObject userProperties;
vector<string> listValue;
listValue.push_back("XX");
userProperties.setList("test",listValue);
ThinkingAnalyticsAPI::user_append(userProperties);
# 五、自动采集事件
ThinkingAnalytics SDK 提供了三种事件的自动采集:
- ta_app_install: 游戏安装,当安装后首次打开游戏会采集该事件
- ta_app_start: 游戏进入前台的时候采集该事件
- ta_app_end: 游戏退到后台的时候采集该事件
通过调用 enableAutoTrack
接口可以开启自动采集:
// 开启自动采集
ThinkingAnalyticsAPI::enableAutoTrack();
注意: 如果您需要自定义访客 ID,请务必在开启自动采集功能之前调用
Identify
接口设置访客 ID.
# 六、其他配置选项
# 6.1 获取设备 ID
SDK 在初始化完成后,会自动生成设备 ID,并记录在本地缓存,对于同一应用/游戏,一台设备的设备 ID 是不变的,可以调用getDeviceId()
获取设备 ID:
ThinkingAnalyticsAPI::getDeviceId();
// 以设备ID作为访客ID
// ThinkingAnalyticsAPI::identify(ThinkingAnalyticsAPI::getDeviceId());
# 6.2 打印上传数据 Log
ThinkingAnalyticsAPI::enableTrackLog(true);
# 6.3 暂停/停止数据上报
- 暂停 SDK 上报(enableTracking)
您可能希望在一些场景下,暂时停止 SDK 的数据采集以及上报,比如用户处于测试环境中、或者用户登录了一个测试账号,此时您可以调用下列接口,暂时停止 SDK 的上报。
您可以通过某一实例(包括主要实例以及轻实例)调用enableTracking
,传入false
来暂停 SDK 的上报,该实例已经设置的#distinct_id
、#account_id
、公共属性等将保留;该实例已经采集但还未上报成功的数据将继续尝试上报;后续该实例不能采集以及上报任何新数据、不能设置访客 ID、账户 ID 以及公共属性等,但是可以读取该实例已经设置的公共属性和设备 ID、访客 ID、账号 ID 等信息。
实例的停止状态将会被保存在本地缓存,直到调用enableTracking
、传入true
,SDK 实例将会重新恢复数据采集以及上报,需要注意轻实例因为不进行缓存,因此每次打开 APP 后,轻实例的暂停状态不会被保留,将重新开启上报。
// 暂停默认实例的上报,已缓存数据和已经设置的信息不被清除
ThinkingAnalyticsAPI::enableTracking(false);
// 恢复默认实例的上报
ThinkingAnalyticsAPI::enableTracking(true);
- 停止 SDK 上报(optOutTracking)
在一些特殊场景下,您可能需要完全停止 SDK 的功能,比如在适用 GDPR 的地区,用户选择不提供数据采集权限,则您可以调用如下接口完全关闭 SDK 的功能。
optOutTracking
只能通过主要实例调用,与enableTracking
的最大区别在于,其将会清空该实例的本地缓存,包括本实例的访客 ID,账号 ID,公共属性,以及未上报的数据队列。之后再关闭该实例的采集和上报功能。
// 停止默认实例的上报, 并清空本地缓存
ThinkingAnalyticsAPI::optOutTracking();
如果您希望关闭 SDK 功能的同时,删除该用户在 TA 集群中的用户数据,可以调用optOutTrackingAndDeleteUser
,这将会在停止 SDK 实例的功能前,上报一条 user_delete
数据,以删除该用户的用户数据。
// 停止默认实例的上报,并发送 user_del
ThinkingAnalyticsAPI::optOutTrackingAndDeleteUser();
实例的停止状态也将保存在本地缓存,直到调用optInTracking
,后续可以继续上报,但此时相当于一个全新的实例
// 重新开启上报
ThinkingAnalyticsAPI::optInTracking();
# 6.4 SDK 运行模式
SDK 支持在三种模式下运行:
- NORMAL: 普通模式,数据会存入缓存,并依据一定的缓存策略上报
- DEBUG: Debug 模式,数据逐条上报。当出现问题时会以日志和异常的方式提示用户
- DEBUG_ONLY: Debug Only 模式,只对数据做校验,不会入库
注意: DEBUG 模式仅仅用于集成阶段数据校验,不要在生产模式下使用。
为了避免 Debug 模式在生产环境上线,规定只有指定的设备才能开启 Debug 模式。只有在客户端开启了 Debug 模式,并且设备 ID 在 TA 后台的"埋点管理"页的"Debug 数据"板块中配置了的设备才能开启 Debug 模式。
设备 ID 可以通过以下三种方式获取:
- TA 平台中事件数据中的 #device_id 属性
- 客户端日志:SDK 初始化完成后会打印设备 DeviceId
- 通过实例接口调用:获取设备 ID
# 6.5 校准时间
SDK 默认会使用本机时间作为事件发生时间上报,如果用户手动修改设备时间会影响到您的业务分析,您可以使用从服务端获取的当前时间戳对 SDK 的时间进行校准。此后,所有未指定时间的调用,包括事件数据和用户属性设置操作,都会使用校准后的时间作为发生时间。
// 1585633785954 为当前 unix 时间戳,单位为毫秒,对应北京时间 2020-03-31 13:49:45
ThinkingAnalyticsAPI::calibrateTime(1585633785954);
我们也提供了从 NTP 获取时间对 SDK 校准的功能。您需要传入您的用户可以访问的 NTP 服务器地址。之后 SDK 会尝试从传入的 NTP 服务地址中获取当前时间,并对 SDK 时间进行校准。如果在默认的超时时间(3 秒)之内,未获取正确的返回结果,后续将使用本地时间上报数据。
// 使用苹果公司 NTP 服务对时间进行校准
ThinkingAnalyticsAPI::calibrateTimeWithNtp("time.apple.com");
注意:
- 您需要谨慎地选择您的 NTP 服务器地址,以保证网络状况良好的情况下,用户设备可以很快的获取到服务器时间。
- 使用 NTP 服务进行时间校准存在一定的不确定性,建议您优先考虑用时间戳校准的方式。
# 七、相关预置属性
# 7.1 获取预置属性
服务端埋点需要 App 端的一些预置属性时,可以通过此方法获取 App 端的预置属性,再传给服务端。
//获取属性对象
PresetProperties* presetProperties = ThinkingAnalyticsAPI::getPresetProperties();
//生成事件预置属性
TDJSONObject* properties = presetProperties->toEventPresetProperties();
/*
{
"#carrier": "中国电信",
"#os": "Android",
"#device_id": "abb8e87bfb5ce66c",
"#screen_height": 2264,
"#bundle_id": "com.sw.thinkingdatademo",
"#manufacturer": "realme",
"#device_model": "RMX1991",
"#screen_width": 1080,
"#system_language": "zh",
"#os_version": "10",
"#network_type": "WIFI",
"#zone_offset": 8
}
*/
//获取某个预置属性
string bundleId = presetProperties->bundleId;//包名
string os = presetProperties->os;//os类型,如Android
string systemLanguage = presetProperties->systemLanguage;//手机系统语言类型
int screenWidth = presetProperties->screenWidth;//屏幕宽度
int screenHeight = presetProperties->screenHeight;//屏幕高度
string deviceModel = presetProperties->deviceModel;//设备型号
string deviceId = presetProperties->deviceId;//设备唯一标识
string carrier = presetProperties->carrier;//手机SIM卡运营商信息,双卡双待时,取主卡的运营商信息
string manufacture = presetProperties->manufacturer;//手机制造商 如HuaWei
string networkType = presetProperties->networkType;//网络类型
string osVersion = presetProperties->osVersion;//系统版本号
double zoneOffset = presetProperties->zoneOffset;//时区偏移值
IP,国家城市信息由服务端解析生成,客户端不提供接口获取这些属性
# 八、进阶功能
Cocos2d-x SDK 支持上报三种特殊类型事件: 首次事件、可更新事件、可重写事件。
# 8.1 首次事件
首次事件是指针对某个设备或者其他维度的 ID,只会记录一次的事件。例如在一些场景下,您可能希望记录在某个设备上第一次发生的事件,则可以用首次事件来上报数据。
// 示例:上报设备首次事件, 假设事件名为 DEVICE_FIRST
TDJSONObject jsonObject;
jsonObject.setString("role","战士");
TDFirstEvent *firstEvent = new TDFirstEvent("DEVICE_FIRST",jsonObject);
ThinkingAnalyticsAPI::track(firstEvent);
如果您希望以设备以外的其他维度来判断是否首次,则可以为首次事件设置 FIRST_CHECK_ID. 例如您需要记录某个账号的首次事件,可以将账号 ID 设置为首次事件的 FIRST_CHECK_ID:
// 示例:上报用户账号的首次事件, 假设事件名为 USER_FIRST
TDJSONObject jsonObject;
TDFirstEvent *firstEvent = new TDFirstEvent("USER_FIRST",jsonObject);
//firstEvent->setFirstCheckId("YOUR_ACCOUNT_ID");
ThinkingAnalyticsAPI::track(firstEvent);
注意:由于在服务端完成对是否首次的校验,首次事件默认会延时 1 小时入库。
# 8.2 可更新事件
您可以通过可更新事件实现特定场景下需要修改事件数据的需求。可更新事件需要指定标识该事件的 ID,并在创建可更新事件对象时传入。TA 后台将根据事件名和事件 ID 来确定需要更新的数据。
// 示例: 上报可被更新的事件,假设事件名为 UPDATABLE_EVENT
TDJSONObject jsonObject;
jsonObject.setNumber("status", 3);
jsonObject.setNumber("price", 100);
TDUpdatableEvent *updatableEvent = new TDUpdatableEvent("UPDATABLE_EVENT",jsonObject,"test_event_id");
// 上报后事件属性 status 为 3, price 为 100
ThinkingAnalyticsAPI::track(updatableEvent);
TDJSONObject jsonObject_new;
jsonObject_new.setNumber("status", 5);
// 上报后事件属性 status 被更新为 5, price 不变
TDUpdatableEvent *updatableEvent = new TDUpdatableEvent("UPDATABLE_EVENT",jsonObject_new,"test_event_id");
ThinkingAnalyticsAPI::track(updatableEvent);
# 8.3 可重写事件
可重写事件与可更新事件类似,区别在于可重写事件会用最新的数据完全覆盖历史数据,从效果上看相当于删除前一条数据,并入库最新的数据。TA 后台将根据事件名和事件 ID 来确定需要更新的数据。
// 示例: 上报可被重写的事件,假设事件名为 OVERWRITABLE_EVENT
TDJSONObject jsonObject;
jsonObject.setNumber("status", 3);
jsonObject.setNumber("price", 100);
TDOverWritableEvent *overWritableEvent = new TDOverWritableEvent("OVERWRITABLE_EVENT",jsonObject,"test_event_id");
ThinkingAnalyticsAPI::track(overWritableEvent);
TDJSONObject jsonObject_new;
jsonObject_new.setNumber("status", 5);
TDOverWritableEvent overWritableEvent_new = new TDOverWritableEvent("OVERWRITABLE_EVENT",jsonObject,"test_event_id");
// 上报后事件属性 status 被更新为 5, price 属性被删除
ThinkingAnalyticsAPI::track(overWritableEvent_new);
# Release Note
# v1.1.1 2021/08/24
- 支持自定义实例名称
- 支持MacOS,Windows平台编译
- 代码优化
- 更新 Android(2.7.3)、iOS SDK(2.7.3)
# v1.1.0 2021/08/24
- 优化初始化API
- 支持动态公共属性
- 支持多实例,轻实例
- 支持时间校准
# v1.0.1 2021/06/28
- 支持预制属性获取
- 优化对Debug模式的支持
# v1.0.0 2021/04/15
- 支持 访客 ID 和 用户账号 的设置
- 支持事件和用户属性上报
- 支持启动/关闭/安装事件的自动上报
- 支持公共属性接口
- 支持 timeEvent 接口