---
code: corona_sdk_installation
name: "Corona"
wikiToken: PVJhwxxtii9DDMkg45ecpCjJnge
parentWikiToken: BAU2w0eipiqGnckeUsIc0mYQnZc
updateTime: 1745310895000
sourceUrl: https://docs-v2.thinkingdata.cn/?version=v5.0&lan=zh-CN&code=corona_sdk_installation
---
# Corona

::: tip 提示

 在接入前, 请先阅读接入前准备。

 您可以在 GitHub 获取 Corona SDK 源码。

 Corona SDK 支持在 iOS、Android 平台运行，大小约为 0.5M

 :::

**最新版本:** v2.0.1

**更新时间:** 2023-11-24

**资源下载: **源码、SDK下载 

::: warning 注意

当前文档适用于 v2.0.0 及以后的版本，历史版本请参考 Corona 接入指南（V1），SDK下载（v1.0.1）

::: 

### 一、集成SDK

- **添加 Corona 配置**
- 下载 Corona SDK 资源文件，解压文件后把 TDAnalytics.lua 复制到 Corona 目录
- **添加 Android 配置**
- 复制 android/ThinkingPluginProxy.java 到 android/plugin/src/main/java/plugin/library 目录
- 使用 Android Studio 打开 Android 项目，切换显示模式为 Android，在 build.gradle 中添加依赖，然后点击 Sync Now 更新
```
dependencies {
    implementation 'cn.thinkingdata.android:ThinkingAnalyticsSDK:3.0.0'
}
```

- 在 plugin.library.LuaLoader 中添加代码
::: tip 提示

如果您没有在 plugin.library.LuaLoader 中扩展功能，可直接拷贝 android/LuaLoader.java 到 android/plugin/src/main/java/plugin/library目录，覆盖原有的 LuaLoader.java 文件。

:::

```
public int invoke(LuaState L) {
   NamedJavaFunction[] luaFunctions = new NamedJavaFunction[] {
      ...
      // ThinkingAnalyticsSDK 添加代码
      new ThinkingBridgingWrapper(),
      ...
   };
   String libName = L.toString( 1 );
   L.register(libName, luaFunctions);
   return 1;
}

public void dispatchEvent(final String message) {
   CoronaEnvironment.getCoronaActivity().getRuntimeTaskDispatcher().send( new CoronaRuntimeTask() {
      @Override
      public void executeUsing(CoronaRuntime runtime) {

         LuaState L = runtime.getLuaState();
         CoronaLua.newEvent( L, EVENT_NAME );
         
         ...
         // ThinkingAnalyticsSDK 添加代码
         JSONObject jsonObject = null;
         String newMessage = null;
         String type = null;
         try {
            jsonObject = new JSONObject(message);
            newMessage = jsonObject.optString("message");
            type = jsonObject.optString("type");
         } catch (Exception ignored) {
         }

         if (!TextUtils.isEmpty(newMessage) && !TextUtils.isEmpty(type)) {
            L.pushString(newMessage);
            L.setField(-2, "message");
            L.pushString(type);
            L.setField(-2, "type");
         } else  {
            L.pushString(message);
            L.setField(-2, "message");
         }
         ...
         
         try {
            CoronaLua.dispatchEvent( L, fListener, 0 );
         } catch (Exception ignored) {
         }
      }
   } );
}

...
// ThinkingAnalyticsSDK 添加代码
@SuppressWarnings({"WeakerAccess", "SameReturnValue"})
public int thinkingBridging(LuaState L) {
   CoronaActivity activity = CoronaEnvironment.getCoronaActivity();
   if (activity == null) {
      return 0;
   }

   String word = L.checkString( 1 );
   JSONObject params = null;
   try {
      params = new JSONObject(word);
   } catch (JSONException e) {
      params = new JSONObject();
   }
   String method = params.optString("method");
   if (method.length() > 0) {
      try {
         Class aClass = Class.forName("plugin.library.ThinkingPluginProxy");
         Method aMethod = aClass.getDeclaredMethod(method, JSONObject.class);
         JSONObject jsonObject = (JSONObject) aMethod.invoke(aClass, params);
         if (jsonObject != null && jsonObject.getClass() == JSONObject.class && jsonObject.has("message")) {
            (new Thread() {
               @Override
               public void run() {
                  dispatchEvent(jsonObject.toString());
               }
            }).start();
         }
      } catch (Exception e) {
         e.printStackTrace();
      }
   }
   return 0;
}
...

...
// ThinkingAnalyticsSDK 添加代码
@SuppressWarnings("unused")
private class ThinkingBridgingWrapper implements NamedJavaFunction {
   @Override
   public String getName() {
      return "thinkingBridging";
   }
   
   @Override
   public int invoke(LuaState L) {
      return thinkingBridging(L);
   }
}
...
```

- **添加 iOS 配置**
- 使用 Xcode 打开 ios 项目，拖拽  ios 目录下的 ThinkingAnalyticsSDK 文件夹到 App 目录
- 开启项目ARC支持，依次选中 TARGETS -> App -> Build Settings -> Objective-C Automatic Reference Counting，并设置为 YES
- 部分文件需要禁用ARC，依次选中 TARGETS -> App -> Build Phases -> Compile Sources -> ThinkingPluginLibrary.mm，并增加设置 -fno-objc-arc
### 二、初始化

```
-- 引入 TDAnalytics
local TDAnalytics = require("TDAnalytics")

-- 初始化 TDAnalytics
local params = {
    appId = "YOUR_APP_ID",
    serverUrl = "YOUR_SERVER_URL"
}
TDAnalytics.init(params)
```

<!-- unsupported block: 34 -->

注意：由于一些设备默认禁止明文传输，因此强烈建议您使用 HTTPS 格式的接收端地址。

### 三、常用功能

#### 3.1 设置账号ID

在用户进行登录时，可调用 `login` 来设置用户的账号 ID，在设置完账号 ID 后，将会以账号 ID 作为用户标识 ID，并且设置的账号 ID 将会在调用 `logout` 之前一直保留：

```
-- 设置账号 ID
TDAnalytics.login("TA")
```

<!-- unsupported block: 34 -->

注意：该方法不会上传用户登录事件。

#### 3.2 设置公共事件属性

对于一些重要的属性，譬如玩家的区服和渠道等，这些属性需要设置在每个事件中，此时您可以将这些属性设置为公共事件属性。公共事件属性指的就是每个事件都会带有的属性，您可以调用 `setSuperProperties()` 来设置公共事件属性，我们推荐您在发送事件前，先设置公共事件属性。

```
-- 设置公共属性
TDAnalytics.setSuperProperties({
    channel = "App Store",
    trip = {"Car", "Train"}
})
```

公共事件属性将会被保存到缓存中，无需每次启动 APP 时调用。如果调用 `setSuperProperties()` 上传了先前已设置过的公共事件属性，则会覆盖之前的属性。如果公共事件属性和 `track()` 上传的某个属性的 `Key` 重复，则该事件的属性会覆盖公共事件属性。

#### 3.3 开启自动采集

通过调用配置初始化参数可以开启自动采集：

```
-- 开启自动采集 
-- appInstall=开启自动采集安装事件
-- appStart=开启自动采集开始事件
-- appEnd=开启自动采集结束事件
local params = {
    appId = "YOUR_APP_ID",
    serverUrl = "YOUR_SERVER_URL",
    autoTrack = {
        "appStart", "appEnd", "appInstall"
    }
}
TDAnalytics.init( params )
```

<!-- unsupported block: 34 -->

注意： 如果您需要自定义访客 ID，请务必在开启自动采集功能之前调用 `identify()` 接口设置访客 ID.

#### 3.4 发送事件

建议您根据先前梳理的文档来设置事件的属性以及发送信息的条件。事件名称是 `string` 类型，只能以字母开头，可包含数字，字母和下划线 "_"，长度最大为 50 个字符，对字母大小写不敏感。

```
TDAnalytics.track( "product_buy", {
    product_name="商品名"
});
```

- 事件属性是 `table` 类型，其中每个元素代表一个属性；
- 事件属性 `Key` 为属性名称，为 `string` 类型，规定只能以字母开头，包含数字，字母和下划线 "_"，长度最大为 50 个字符，对字母大小写不敏感；
- 属性值支持六种类型：字符串、数值类、`bool`、`Array` 、对象、对象组类型。
复杂数据类型，属性可传入对象和对象组：

#### 3.5 设置用户属性

对于一般的用户属性，您可以调用 `userSet()` 来进行设置，使用该接口上传的属性将会覆盖原有的属性值，如果之前不存在该用户属性，则会新建该用户属性。

```
-- 设置用户属性
TDAnalytics.userSet({
    user_name = "TE"
})
```

<!-- unsupported block: 34 -->

属性格式要求与事件属性保持一致。

### 四、最佳实践

以下示例代码包含以上所有操作，我们推荐按照如下步骤使用:

```
-- 引入 TDAnalytics
local TDAnalytics = require("TDAnalytics")

if (授权隐私政策) {
    -- 初始化SDK
    local params = {
        appId = "YOUR_APP_ID",
        serverUrl = "YOUR_SERVER_URL"
    }
    TDAnalytics.init(params)
    
    --如果用户已登录，可以设置用户的账号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"
    })
}
```
