菜单

CocosCreator

ⓘ 提示
CocosCreator 3.x
Android 要求最低系统版本为 Android 4.4

一、集成

1.1 下载cocos-sdk压缩包

下载链接:dt-cocos-sdk

如果您使用的是Cocos 2.x版本,请下载:dt-cocos-sdk(2.x)

1.2 集成 JS SDK

  • TypeScript ESModule 项目
    1. 将压缩包中的 dt.cc.mjs、dt.cc.d.mts(2.x版本使用压缩包中的cocos.js和coco.d.ts) 放入项目 assets/libs 目录下,如果 libs 不存在,新建 libs 目录
    2. 在 assets/scripts/ 目录下的文件中导出使用
      TypeScript 复制代码
      import { DataTower } from '../lib/dt.cc.mjs';
  • JavaScript CommonJS 项目
    1. 将压缩包中的 dt.cc.cjs、dt.cc.d.cts 放入项目 assets/libs 目录下,如果 libs 不存在,新建 libs 目录
    2. 在 assets/scripts/ 目录下的文件中导出使用
      JavaScript 复制代码
      const { DataTower } = require('../lib/dt.cc.cjs')

1.3 Android 端集成

Maven Central
  1. 在项目根目录下 build.gradle 文件中添加 mavenCentral 仓库

    kotlin 复制代码
    allprojects {
        repositories {
            ...
            mavenCentral()
        }
    }
  2. 在项目主工程目录下 build.gradle 文件中添加 SDK 依赖

    kotlin 复制代码
    dependencies {
        ...
    
       implementation 'ai.datatower:core:{最新版本}'
    }
  3. 将 DTCocosCreatorProxyApi.java 放到 {项目地址}/native/engine/android/app/src/ 下。如果您使用的是2.x的版本,则将压缩包中的 DTCocosCreatorProxyApi.java,放到/app/src/org/cocos2dx/javasrcipt/下,如:

  1. proguard 规则中加入 ({项目地址}/native/engine/android/app/proguard-rules.pro):
    复制代码
    -keep class ai.datatower.bridge.DTCocosCreatorProxyApi { *; }

1.3 iOS 端集成

1. 集成二进制文件

1. 方式一,手动集成

把压缩包中的DataTowerAICore.framework 引入工程

引入系统库 CoreTelephony

添加-all_load标志, target -> build Settings -> Other Linker Flags

参考 iOS静态库使用category问题

2. 方式二,自动集成 (推荐)

目前仅支持pod自动集成方式

pod 复制代码
1. 先安装pod,安装成功后,进入项目目录,运行pod init,会生成podfile
2. 在podfile里添加相应配置
      pod "DataTowerAICore", "~> 3.0.0"
3. 执行 pod install
4. 打开xxx.xcworkspace项目

2. 添加源文件

  1. 把压缩包中的DTCocosCreatorProxyApi.h 和 DTCocosCreatorProxyApi.mm 添加到项目中

  2. 现在可以进行编译

3. 常见问题

  1. 编译报错,fatal error: 'DataTowerAICore/DTAnalytics.h' file not found
    手动和自动集成都有可能遇到,
    如果是手动集成,添加framework的路径到framework search paths
    如果是自动集成,可以添加$(inherited)到framework search paths,再执行一次 pod install

  2. 运行报错 unrecognized selector sent to class
    手动集成会遇到,添加-all_load标志,见手动集成指引

二、初始化

  • 说明

DataTower.ai Core SDK 唯一初始化入口

  • 方法
typescript 复制代码
class DataTower {
    static initSDK(config: Config): void;
}
  • 参数
参数名 类型 是否必传 说明 示例
appId string 是 项目唯一标识,创建项目后 DT 后台自动分配,请在【项目设置-项目详情】中获取 dt_test
serverUrl string 是 数据上报地址,创建项目后 DT 后台自动分配,请在【项目设置-项目详情】中获取 https://xxx.roiquery.com
channel string 否 渠道,打多渠道包时需要用到,可使用 SDK 内部提供的实现, 默认为“” DTChannel.GP
isDebug boolean 否 是否打开调试,调试模式下将打印 log,默认为 false,log 标签为 DataTower true/false
logLevel number 否 log 的级别,默认为 LogLevel.VERBOSE,仅在 isDebug = true 有效 Log.VERBOSE、Log.DEBUG、Log.ERROR 等
manualEnableUpload boolean 否 是否手动启动上报, 如设为 true, 则需要自行调用 enableUpload 开启上报 true/false
  • 使用
typescript 复制代码
//  DT SDK 初始化
DataTower.initSDK({
    appId: "app_id",
    serverUrl: "https://example.com",
    channel: "",
    isDebug: true,
    logLevel: LogLevel.VERBOSE,
    manualEnableUpload: false,
});

三、基础功能

3.1 ID 体系

3.1.1 设置账号 ID

  • 说明

可以在用户每一次登录时,调用 setAccountId 设置用户的账号 ID, DT 系统将会以账号 ID 作为身份识别 ID,多次调用 setAccountId 将覆盖先前的账号 ID

若您的应用没有账号体系可以不设置

  • 方法
typescript 复制代码
class DataTower {
    static setAccountId(id: string): void;
}
  • 参数
参数名 类型 是否必传 说明
id string 是 自有用户系统的 id
  • 使用
typescript 复制代码
DataTower.setAccountId("123456");

如果需要清除账号 ID,请传入空字符串

typescript 复制代码
DataTower.setAccountId("");

3.1.2 获取 DT ID

  • 说明

异步获取由 SDK 生成的设备标识 DT ID。

  • 方法
typescript 复制代码
class DataTower {
    static getDataTowerId(callback: (id: string) => void): void;
    static getDataTowerId(): Promise<string>;
}
  • 参数
参数名 类型 是否必传 说明
callback (id: string) => void 否 用户接收 dt id 的回调
  • 使用
typescript 复制代码
DataTower.getDataTowerId((id) => console.log(id));
// or
const id = await DataTower.getDataTowerId();

3.2 设置事件上报

  • 说明

调用 track 设置自动上报的埋点事件和事件属性

  • 方法
typescript 复制代码
class DataTower {
    static track(
        eventName: string,
        properties: Record<string, any>
    ): void;
}
  • 参数
参数名 类型 是否必传 说明
eventName string 是 事件名称
properties Record<string,any> 是 自定义事件属性
  • 使用
typescript 复制代码
DataTower.track("test_track", {
    test_property_1: "test",
    test_property_2: 1,
});

3.3 设置用户属性

DT 系统支持的用户属性设置类型总览说明如下

操作 对应事件名 处理规则
覆盖用户属性 #user_set 对用户表进行操作,覆盖用户的原有属性值,如果之前不存在该用户属性,则会新建该用户属性,类型与覆盖操作传入属性的类型一致
初始化用户属性 #user_set_once 对用户表进行操作,初始化用户属性,如果该属性已有值存在,系统忽略本次操作
累加用户属性 #user_add 对用户表进行操作,对数值型的用户属性做累加计算,如果该属性还未被设置,则会赋值 0 后再进行计算,可传入负值等同于相减操作
清空用户属性值 #user_unset 对用户表进行操作,清空用户属性的属性值,即设置成 NULL,如果被清空的属性不存在也不会新建该属性
追加列表型用户属性的元素 #user_append 对用户表进行操作,对列表类型的用户属性追加元素,如果被追加的列表属性不存在,系统将自动生成并进行追加
追加并去重列表类型用户属性的元素 #user_uniq_append 对用户表进行操作,对列表类型的用户属性值追加元素,并会进行一次全列表去重(去重保证前后原有的元素顺序不变),如果被追加的列表属性不存在,系统将自动生成并进行追加再去重

3.3.1 user_set

  • 说明

对于一般的用户属性,您可以调用 userSet 来进行设置,使用该接口上传的属性将会覆盖原有的属性值,如果之前不存在该用户属性,则会新建该用户属性,类型与覆盖操作传入属性的类型一致

  • 方法
typescript 复制代码
class DataTower {
    static userSet(properties: Record<string, any>): void;
}
  • 参数
参数名 类型 是否必传 说明
properties Record<string, any> 是 事件属性
  • 使用
typescript 复制代码
DataTower.userSet({
    user_sex_man: false,
    user_pwd: "1111111",
    user_age: 23,
});

3.3.2 user_set_once

  • 说明

如果您要上传的用户属性只要设置一次,则可以调用 userSetOnce 来进行设置,当该属性之前已经有值的时候,将会忽略这条信息

  • 方法
typescript 复制代码
class DataTower {
    static userSetOnce(
        properties: Record<string, any>
    ): void;
}
  • 参数
参数名 类型 是否必传 说明
properties Record<string, any> 是 事件属性
  • 使用
typescript 复制代码
DataTower.userSetOnce({
    user_first_paid_time: "2020-09-23",
});

3.3.3 user_add

  • 说明

当您要上传数值型的属性时,您可以调用 userAdd 来对该属性进行累加操作,如果该属性还未被设置,则会赋值 0 后再进行计算,可传入负值,等同于相减操作

  • 方法
typescript 复制代码
class DataTower {
    static userAdd(properties: Record<string, number>): void;
}
  • 参数
参数名 类型 是否必传 说明
properties Record<string, number> 是 事件属性 设置的属性 key 为字符串,Value 只允许为数值,否则操作不生效
  • 使用
typescript 复制代码
DataTower.userAdd({ total: 30 });
// 此时"total"为30
DataTower.userAdd({ total: 648 });
// 此时"total"为678

3.3.4 user_unset

  • 说明

当您要清空用户的用户属性值时,您可以调用 userUnset 来对指定属性进行清空操作,如果该属性还未创建,则 userUnset 不会创建该属性

  • 方法
typescript 复制代码
class DataTower {
    static userUnset(properties: string[]): void;
}
  • 参数
参数名 类型 是否必传 说明
properties string[] 是 用户属性名称集
  • 使用
typescript 复制代码
DataTower.userUnset(["key1"]);

3.3.5 user_delete

  • 说明 如果您要删除某个用户,可以调用 user_delete 将这名用户删除,您将无法再查询该名用户的用户属性,但该用户产生的事件仍然可以被查询到。
  • 方法
typescript 复制代码
class DataTower {
    static userDelete(): void;
}

3.3.6 user_append

  • 说明

您可以调用 userAppend 对列表类型的用户数据追加元素

  • 方法
typescript 复制代码
class DataTower {
    static userAppend(
        properties: Record<string, any[]>
    ): void;
}
  • 参数
参数名 类型 是否必传 说明
properties Record<string, any[]> 是 用户属性名称集
  • 使用
typescript 复制代码
DataTower.userAppend({ user_list: ["apple", "cube"] });

3.3.7 user_uniq_append

  • 说明

您可以调用 userUniqAppend 对列表的用户数据追加唯一元素。调用 userUniqAppend 接口会对追加的用户属性进行去重, userAppend 接口不做去重,用户属性可存在重复

  • 方法
typescript 复制代码
class DataTower {
    static userUniqAppend(
        properties: Record<string, any[]>
    ): void;
}
  • 参数
参数名 类型 是否必传 说明
properties Record<string, any[]> 是 用户属性名称集
  • 使用
typescript 复制代码
// 此时user_list的属性值为["apple","ball"]
DataTower.userUniqAppend({ user_list: ["apple", "ball"] });
// 此时user_list的属性值为["apple","apple","ball","cube"]
DataTower.userUniqAppend({ user_list: ["apple", "cube"] });

四、进阶功能

4.1 收入数据上报

4.1.1 广告变现(IAA)全链路

  • 说明
  1. 如果你的产品具备广告变现(IAA)功能,DT SDK 已经预置了一些常用的广告事件接口。在产品的广告变现相关场景中,你可以调用相应的接口。一旦调用了这些接口成功,您可以在我们的后台实时查看广告变现全链路的表现数据。
  2. 并不是所有事件都要求上报,但是上报的越详细,越有助于分析整个广告变现链路。如果预置事件中没有满足你的需求,你仍可以自定义事件。DT 中针对一个广告变现流程(加载、展示、行为、转化、关闭等),使用了唯一的 seq 用来关联和区分。如果你想关联同一个广告变现流程中预置事件和自定义事件,请使用 seq 进行关联。
  3. 如果需要查看设备层级广告收入预估,请务必调用以下接口上报相关事件:
接口名
reportShow
reportPaid
reportClick
reportRewarded
reportConversionByClick
reportConversionByRewarded
reportConversionByLeftApp
  1. 如果需要查看广告变现漏斗,请务必调用以下接口上报相关事件:
接口名
reportToShow
reportShow
reportClick
reportRewarded
  • 接口列表
typescript 复制代码
// 上报广告开始加载事件
class DataTower {
    static reportLoadBegin(opts: {
        id: string;
        type: AdType;
        platform: AdPlatform;
        seq: string;
        properties?: Record<string, any>;
        mediation?: AdMediation;
        mediationId?: string;
    }): void;

    // 上报广告结束加载事件
    static reportLoadEnd(opts: {
        id: string;
        type: AdType;
        platform: AdPlatform;
        duration: number;
        result: boolean;
        seq: string;
        errorCode: number;
        errorMessage: string;
        properties?: Record<string, any>;
        mediation?: AdMediation;
        mediationId?: string;
    }): void;

    // 上报广告预展示事件,在想展示广告之前调用
    static reportToShow(opts: {
        id: string;
        type: AdType;
        platform: AdPlatform;
        location: string;
        seq: string;
        properties?: Record<string, any>;
        entrance?: string;
        mediation?: AdMediation;
        mediationId?: string;
    }): void;

    // 上报广告展示事件,在展示广告时调用
    static reportShow(opts: {
        id: string;
        type: AdType;
        platform: AdPlatform;
        location: string;
        seq: string;
        properties?: Record<string, any>;
        entrance?: string;
        mediation?: AdMediation;
        mediationId?: string;
    }): void;

    // 上报广告展示失败事件,在展示广告失败时调用
    static reportShowFailed(opts: {
        id: string;
        type: AdType;
        platform: AdPlatform;
        location: string;
        seq: string;
        errorCode: number;
        errorMessage: string;
        properties?: Record<string, any>;
        entrance?: string;
        mediation?: AdMediation;
        mediationId?: string;
    }): void;

    // 上报广告关闭事件,在广告被关闭时调用
    static reportClose(opts: {
        id: string;
        type: AdType;
        platform: AdPlatform;
        location: string;
        seq: string;
        properties?: Record<string, any>;
        entrance?: string;
        mediation?: AdMediation;
        mediationId?: string;
    }): void;

    // 上报广告点击事件,在广告被点击时调用
    static reportClick(opts: {
        id: string;
        type: AdType;
        platform: AdPlatform;
        location: string;
        seq: string;
        properties?: Record<string, any>;
        entrance?: string;
        mediation?: AdMediation;
        mediationId?: string;
    }): void;

    // 上报广告获得奖励事件,在激励广告获取奖励后调用
    static reportRewarded(opts: {
        id: string;
        type: AdType;
        platform: AdPlatform;
        location: string;
        seq: string;
        properties?: Record<string, any>;
        entrance?: string;
        mediation?: AdMediation;
        mediationId?: string;
    }): void;

    // 上报广告收益转化事件,在点击广告时调用(#ad_conversion_source = by_click)
    static reportConversionByClick(opts: {
        id: string;
        type: AdType;
        platform: AdPlatform;
        location: string;
        seq: string;
        properties?: Record<string, any>;
        entrance?: string;
        mediation?: AdMediation;
        mediationId?: string;
    }): void;

    // 上报广告收益转化事件,在获得广告激励时调用(#ad_conversion_source = by_rewarded)
    static reportConversionByRewarded(opts: {
        id: string;
        type: AdType;
        platform: AdPlatform;
        location: string;
        seq: string;
        properties?: Record<string, any>;
        entrance?: string;
        mediation?: AdMediation;
        mediationId?: string;
    }): void;

    // 上报广告收益转化事件,在点击广告后跳出App时调用(#ad_conversion_source = by_left_app)
    static reportConversionByLeftApp(opts: {
        id: string;
        type: AdType;
        platform: AdPlatform;
        location: string;
        seq: string;
        properties?: Record<string, any>;
        entrance?: string;
        mediation?: AdMediation;
        mediationId?: string;
    }): void;

    // 上报广告展示价值事件,在广告SDK回调时调用
    static reportPaid(opts: {
        id: string;
        type: AdType;
        platform: AdPlatform;
        location: string;
        seq: string;
        value: string;
        currency: string;
        precision: string;
        properties?: Record<string, any>;
        entrance?: string;
        mediation?: AdMediation;
        mediationId?: string;
    }): void;

    static reportPaid(opts: {
        id: string;
        type: AdType;
        platform: AdPlatform;
        location: string;
        seq: string;
        mediation: AdMediation;
        mediationId: string;
        value: string;
        precision: string;
        country: string;
        properties?: Record<string, any>;
    }): void;

    // 上报离开app事件,在点击广告链接,离开当前app(页面)时调用
    static reportLeftApp(opts: {
        id: string;
        type: AdType;
        platform: AdPlatform;
        location: string;
        seq: string;
        properties?: Record<string, any>;
        entrance?: string;
        mediation?: AdMediation;
        mediationId?: string;
    }): void;
}
  • 参数
参数名 类型 是否必传 说明
seq string 是 广告系列事件的标识,需要调用 DTAdReport.generateUUID()生成
id string 是 Network 广告单元 ID
type AdType 是 详见 类型 Type
platform AdPlatform 是 详见 广告平台 Platform
entrance string 否 广告展示入口
result boolean 是 广告加载结果,true 为广告加载成功
duration number 是 广告加载时长
location string 是 广告位置,通常为在广告平台配置的位置值
errorCode number 否 失败码,值为应用接入的对应的广告平台给出的错误码
errorMessage string 否 失败信息,应用接入的对应的广告平台给出的错误信息
value string 是 广告价值,应用接入的对应的广告平台给出的广告价值信息
currency string 是 广告价值对应的货币单位,请传入 USD
precision string 是 精确度,广告价值所对应的精确度
country string 是 广告展示所在的国家/地区信息
mediation AdMediation 否 详见 聚合广告平台 Mediation
mediationId string 否 聚合平台广告单元 ID
properties Record<string, any> 否 应用自定义的额外属性
  • 使用事例

场景一:独立广告平台

typescript 复制代码
/*
* 一次展示Admob插页广告的过程
*/

// 广告位,比如这页面是主页
const location = "main";

// Admob广告单元
const adUnit = "xxxxxxxx";

// 整个过程的行为系列标识
const seq = "xxx";

// 1.上报开始加载广告
DataTower.reportLoadBegin({
    id: adUnit,
    type: AdType.INTERSTITIAL,
    platform: AdPlatform.ADMOB,
    seq: seq,
});

// 2.Admob开始加载广告
// 加载开始时间
const loadStartTime = new Date().getTime();

// 3.上报加载广告成功
DataTower.reportLoadEnd({
    id: adUnit,
    type: AdType.INTERSTITIAL,
    platform: AdPlatform.ADMOB,
    duration: new Date().getTime() - loadStartTime,
    result: true,
    seq: seq,
});
// 3.上报加载广告失败
DataTower.reportLoadEnd({
    id: adUnit,
    type: AdType.INTERSTITIAL,
    platform: AdPlatform.ADMOB,
    duration: new Date().getTime() - loadStartTime,
    result: false,
    seq: seq,
    errorCode: 1001,
    errorMessage: "广告加载失败",
});

// 4.展示广告
DTAdReport.reportToShow(
    adUnit,
    AdType.INTERSTITIAL,
    AdPlatform.ADMOB,
    location,
    seq
);

// 5.广告展示成功
DataTower.reportShow({
    id: adUnit,
    type: AdType.INTERSTITIAL,
    platform: AdPlatform.ADMOB,
    location: location,
    seq: seq,
});

// 6.广告展示失败
DataTower.reportShowFailed({
    id: adUnit,
    type: AdType.INTERSTITIAL,
    platform: AdPlatform.ADMOB,
    location: location,
    seq: seq,
    errorCode: 1001,
    errorMessage: "广告加载失败",
});

// 7.广告被点击
DataTower.reportClick({
    id: adUnit,
    type: AdType.INTERSTITIAL,
    platform: AdPlatform.ADMOB,
    location: location,
    seq: seq,
});

// 8.广告关闭
DataTower.reportClose({
    id: adUnit,
    type: AdType.INTERSTITIAL,
    platform: AdPlatform.ADMOB,
    location: location,
    seq: seq,
});

对于激励广告,会有获得激励回调

typescript 复制代码
DataTower.reportConversionByRewarded({
    id: adUnit,
    type: AdType.REWARDED,
    platform: AdPlatform.ADMOB,
    location: location,
    seq: seq,
});

场景二:聚合广告平台(Mediation)

由于聚合广告平台展示广告的时候,通常没有返回具体是哪个广告平台(Network)的广告和对应信息,所以需要在回调中判断,如 onAdShowed 回调

typescript 复制代码
// 聚合广告平台一般会返回广告相关的信息 AdInfo
const adInfo: AdInfo = ...;
// 需自行实现 getAdPlatform() 、getAdUnit()方法
const adPlatform = getAdPlatform(ad);
const adUnit = getAdUnit(ad);
// 广告展示成功
DataTower.reportShow({
    id: adUnit,
    type: AdType.INTERSTITIAL,
    platform: adPlatform,
    location: location,
    seq: seq,
});

其他 API 类似

4.1.2 内购变现(IAP)全链路(beta)

  • 说明

如果你的产品具备内购变现(IAP)功能,DT SDK 已经预置了一些常用的事件接口。在产品的内购变现相关场景中,你可以调用相应的接口。一旦调用了这些接口成功,您可以在我们的后台实时查看内购变现全链路的表现数据。

  • 方法
typescript 复制代码
// 上报购买成功事件,购买成功的时候上报
class DataTower {
    static reportPurchaseSuccess(opts: {
        order: string;
        sku: string;
        price: number;
        currency: string;
        properties: Record<string, any>;
    }): void;
}
  • 参数
参数名 类型 是否必传 说明
currency string 是 购买所用的货币单位,与 price 共同决定购买所需的价格
price number 是 购买所需的价格
sku string 是 购买商品 id
order string 是 购买订单
properties Record<string, any> 是 应用自定义的额外属性

4.1.3 订阅变现(IAS)全链路(beta)

  • 说明

如果你的产品具备内购变现(IAS)功能,DT SDK 已经预置了一些常用的事件接口。在产品的订阅变现相关场景中,你可以调用相应的接口。一旦调用了这些接口成功,您可以在我们的后台实时查看订阅变现全链路的表现数据。

  • 方法
typescript 复制代码
// 订阅成功事件上报,订阅成功时上报
class DataTower {
    static reportSubscribeSuccess(opts: {
        sku: string;
        price: number;
        currency: string;
        properties: Record<string, any>;
        originalOrderId: string;
        orderId: string;
    }): void;
}
  • 参数
参数名 类型 是否必传 说明
currency string 是 订阅所用的货币单位,与 price 共同决定订阅所需的价格
price number 是 订阅所需的价格
sku string 是 订阅商品 id
orderId string 是 订阅订单
originalOrderId string 是 订阅原始订单 id
properties Record<string, any> 是 应用自定义的额外属性

4.2 集成三方数据

4.2.1 透传 dt_id

如果您需将三方数据同步至 DT 平台,请在三方 SDK 初始化之前调用 get dt_id 的方法,然后按照 DT 集成各平台的操作文档传入三方平台的对应参数

TypeScript 复制代码
DataTower.getDataTowerId((dt_id) => {})
// 或
const id = await DataTower.getDataTowerId();

4.2.2 user_set 三方 ID

如果您需将 DT 数据从服务端发送至三方平台,请初始化三方 SDK 之后获取三方 ID,然后使用 DT SDK 进行数据上报,完成 dt_id 和三方 ID 的绑定

TypeScript 复制代码
// 需先获取对应 id
// Firebase
DataTower.setFirebaseAppInstanceId("");
// Kochava
DataTower.setKochavaId("");
// AppsFlyer
DataTower.setAppsFlyerId("");
// Adjust
DataTower.setAdjustId("");

4.3 事件时长计时

  • 说明

如果您需要记录某个事件的持续时长,可以调用 trackTimerStart 来开始计时。

在事件开始时,调用 trackTimerStart 并不会真正发送事件;在事件结束时调用 trackTimerEnd,SDK 会上报 "event" 事件,并自动在"event" 事件属性中加入 #duration 这一属性来表示记录的事件持续时长。

  • 方法
typescript 复制代码
// 开始事件计时
DataTower.trackTimerStart("event");

// 如果需要暂停事件计时
DataTower.trackTimerPause("event");

// 如果需要恢事件计时
DataTower.trackTimerResume("event");

// 结束事件计时, properties 为自定义属性,Record<string, any>
DataTower.trackTimerEnd("event", { key: "value" });
最近修改: 2026-08-04Powered by