菜单

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.mjsdt.cc.d.mts(2.x版本使用压缩包中的cocos.jscoco.d.ts) 放入项目 assets/libs 目录下,如果 libs 不存在,新建 libs 目录
    2. 在 assets/scripts/ 目录下的文件中导出使用
      TypeScript 复制代码
      import { DataTower } from '../lib/dt.cc.mjs';
  • JavaScript CommonJS 项目
    1. 将压缩包中的 dt.cc.cjsdt.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" });
上一个
Flutter
下一个
JavaScript
最近修改: 2025-04-25