Skip to content
Last updated

Unity SDK

The Unity SDK for Treasure Data allows you to import events from your Unity applications into Treasure Data easily. With this SDK, you can send data from your Unity application to Treasure Data without having to install anything on your server-side to track mobile app activities.

Prerequisites

  • Basic knowledge of Unity Development
  • Basic knowledge of Treasure Data
  • Treasure Data Write-Only API Key

Our Unity SDK is available through Github. Check the repository to ensure that you have the most recent SDK:

Setup

Download this Unity package and import it into your Unity project using Assets -> Import Package -> Custom Package.

For iOS Application Development

On Xcode, add Treasure Data iOS SDK to your Podfile as following:

platform :ios, '12.0'

target 'Unity-iPhone' do
  use_frameworks!
  inherit! :search_paths
end

target 'UnityFramework' do
  use_frameworks!

  pod 'TreasureData-iOS-SDK', '= 1.0.1'
end

Basic Usage

Instantiate the TreasureData Object with Your API Key

public class MyTreasureDataPlugin : MonoBehaviour {
#if UNITY_IPHONE || UNITY_ANDROID
  [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
  static void OnRuntimeInitialization() {
    TreasureData.InitializeApiEndpoint("https://us01.records.in.treasuredata.com");
    TreasureData.InitializeApiKey("YOUR_API_KEY");
  }
#endif
}

Treasure Data strongly recommends that you use a write-only API key for ingest and import operations and whenever using Treasure Data SDKs.

How to get a Write-Only API Key
  1. Login to the Treasure Data Console and go to the API Key page.
  2. If you don't already have a write-only API key, then create one. From the top right, select Actions > Create API Key.
  3. Name the new API Key.
  4. From the Type drop-down menu, select Write-only.
  5. Select Save.
  6. Copy your new Write-Only API Key and use it authenticate the APIs in your project.

Add an Event to a Local Buffer

To add an event to a local buffer, use the AddEvent function.

Simple
TreasureData.Instance.AddEvent("testdb", "unitytbl", ev);
Advanced
Dictionary<string, object> ev = new Dictionary<string, object>();
ev["str"] = "strstr";
ev["int"] = 12345;
ev["long"] = 12345678912345678;
ev["float"] = 12.345;
ev["double"] = 12.3459832987654;
ev["bool"] = true;
TreasureData.Instance.AddEvent("testdb", "unitytbl", ev,
    delegate() {
        Debug.LogWarning ("AddEvent Success!!!");
    },
    delegate(string errorCode, string errorMsg) {
        Debug.LogWarning ("AddEvent Error!!! errorCode=" + errorCode + ", errorMsg=" + errorMsg);
    }
);

Specify the database and table to which you want to import the events. The total length of database and table must be shorter than 129 characters.

Upload Events to Treasure Data

To upload buffered events to Treasure Data, use the UploadEvents function. You can call this API to upload buffered events whenever you want.

Simple
TreasureData.Instance.UploadEvents();
Advanced
TreasureData.Instance.UploadEvents (
    delegate() {
        Debug.LogWarning ("UploadEvents Success!!! ");
    },
    delegate(string errorCode, string errorMsg) {
        Debug.LogWarning ("UploadEvents Error!!! errorCode=" + errorCode + ", errorMsg=" + errorMsg);
    }
);

The characteristics of your application will determine when and how often to upload buffered events. Treasure Data recommends that you upload at the following times:

  • When the current screen is closing or moving to background
  • When closing the application

UploadEvents buffers for a few minutes before the import into Treasure Data storage begins.

Retry Uploading and Deduplication

This SDK imports events in exactly once style with the combination of these features:

  • This SDK keeps buffered events with adding unique keys and retries to upload them until confirming the events are uploaded and stored on server side (at least once)
  • The server side remembers the unique keys of all events within the past hour by default and prevents duplicated imports (at most once)

The deduplication window is one hour by default, so it's important not to keep buffered events longer than that to avoid duplicated events.

Start/End Session

When you call StartGlobalSession method, the SDK generates a session that's kept until EndGlobalSession is called. The session id will be output as a column name "td_session_id" in Treasure Data. Also, you can get the session id with GetGlobalSessionId.

TreasureData.InitializeDefaultDatabase("testdb");
td = new TreasureData("your_api_key");
print("Session ID = " + TreasureData.GetSessionId());   // >>> (null)

TreasureData.StartGlobalSession();
print("Session ID = " + TreasureData.GetSessionId());   // >>> cad88260-67b4-0242-1329-2650772a66b1
    :
TreasureData.Instance.AddEvent("testdb", "unitytbl", ev);
    :
TreasureData.EndGlobalSession();
print("Session ID = " + TreasureData.GetSessionId());   // >>> (null)
    :
TreasureData.Instance.AddEvent("testdb", "unitytbl", ev);

// Outputs =>>
//   [{"td_session_id":"cad88260-67b4-0242-1329-2650772a66b1",
//       ..., "time":1418880000},
//        :
//    {..., "time":1418880123}
//   ]

The session continues from when StartGlobalSession is called until EndGlobalSession is called. If StartGlobalSession is called within 10 seconds of an EndGlobalSession call, then the previous session resumes; a new session is not created.

If you want to use instance-level, fine-grained sessions, you can use TreasureData#StartSession(tableName) / TreasureData#EndSession(tableName) / TreasureData#GetSessionId(), which add a session event at calling StartSession / EndSession and don't have the session resume feature.

Advanced Usage

Tracking Application Lifecycle Events

The SDK can be optionally enabled to automatically capture app lifecycle events (disabled by default). You must explicitly enable this option. You can set the target table through DefaultTable:

[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
static void OnRuntimeInitialization() {
  // TreasureData client setup...
  TreasureData.DefaultTable = "app_lifecycles";
  TreasureData.Instance.EnableAppLifecycleEvent();
}

There are three kinds of events that are tracked automatically:

  • Application Open
  • Install
  • Update
Application Open
{
    "td_unity_event": "TD_UNITY_APP_OPEN",
    "td_app_ver": "1.0",
    ...
}
Application Install
{
    "td_unity_event": "TD_UNITY_APP_INSTALL",
    "td_app_ver": "1.0",
    ...
}
Application Update
{
    "td_unity_event": "TD_UNITY_APP_UPDATE",
    "td_app_ver": "1.1",
    "td_app_previous_ver": "1.0",
    ...
}

Tracking In-App Purchase Events

If enabled, the Treasure Data SDK can automatically track IAP events without having to listen and call addEvent yourself. Enable or disable this feature using the following:

enableInAppPurchaseEvent
TreasureData.sharedInstance.enableInAppPurchaseEvent();
disableInAppPurchaseEvent
TreasureData.sharedInstance.disableInAppPurchaseEvent();

In-App purchase event tracking is disabled by default.

Depending on the native platform your application is running on, the event's schema might be different:

AndroidiOS
  • td_android_event
  • td_iap_product_id
  • td_iap_order_id
  • td_iap_product_price
  • td_iap_quantity
  • td_iap_product_price_amount_micros
  • td_iap_product_currency
  • td_iap_purchase_time
  • td_iap_purchase_token
  • td_iap_purchase_state
  • td_iap_purchase_developer_payload
  • td_iap_product_type
  • td_iap_product_title
  • td_iap_product_description
  • td_iap_package_name
  • td_iap_subs_auto_renewing
  • td_iap_subs_status
  • td_iap_subs_period
  • td_iap_free_trial_period
  • td_iap_intro_price_period
  • td_iap_intro_price_cycless
  • td_iap_intro_price_amount_micros
  • td_ios_event
  • td_iap_transaction_identifier
  • td_iap_transaction_date
  • td_iap_quantity
  • td_iap_product_identifier
  • td_iap_product_price
  • td_iap_product_localized_title
  • td_iap_product_localized_description
  • td_iap_product_currency_code

For the more details of these columns' value please see the Android / iOS SDK documentation:

Additional Configuration

Endpoint

The API endpoint (default: https://us01.records.in.treasuredata.com) is modified using the InitializeApiEndpoint:

TreasureData.InitializeApiEndpoint("https://us01.records.in.treasuredata.com");

Encryption Key

If you've set an encryption key via TreasureData.InitializeEncryptionKey(), the SDK saves the event data as encrypted when it calls AddEvent.

TreasureData.InitializeEncryptionKey("hello world");
    :
TreasureData.Instance.AddEvent("testdb", "unitytbl", ev);

Default Database

TreasureData.InitializeDefaultDatabase("testdb");
    :
TreasureData.Instance.AddEvent("unitytbl", ev);

Adding the UUID of the Device Automatically to Each Event

The UUID of the device is added to each event automatically if you call EnableAutoAppendUniqId. This value won't change until the application is uninstalled.

TreasureData.Instance.EnableAutoAppendUniqId();
    :
TreasureData.Instance.AddEvent("unitytbl", "name", "foobar");
// Outputs =>>
//   {"td_uuid_id":"cad88260-67b4-0242-1329-2650772a66b1", "name":"foobar", ... }

It outputs the value as a column name td_uuid.

Adding an UUID to Each Event Record Automatically

The UUID will be added to each event record automatically if you call EnableAutoAppendRecordUUID. Each event has different UUID.

TreasureData.Instance.EnableAutoAppendRecordUUID();
// If you want to customize the column name, pass it to the API
// TreasureData.Instance.EnableAutoAppendRecordUUID("my_record_uuid");
    :
TreasureData.Instance.AddEvent(...);

It outputs the value as a column name record_uuid by default.

Adding the Device Model Information to Each Event Automatically

Device model information is added to each event automatically if you call EnableAutoAppendModelInformation.

TreasureData.Instance.EnableAutoAppendModelInformation();
    :
TreasureData.Instance.AddEvent("unitytbl", "name", "foobar");
// Outputs =>>
//   {"td_device":"iPod touch", "name":"foobar", ... }

It outputs the following column names and values:

iOSAndroid
  • td_device : UIDevice.model
  • td_model : UIDevice.model
  • td_os_ver : UIDevice.model.systemVersion
  • td_os_type : "iOS"
  • td_board : android.os.Build#BOARD
  • td_brand : android.os.Build#BRAND
  • td_device : android.os.Build#DEVICE
  • td_display : android.os.Build#DISPLAY
  • td_model : android.os.Build#MODEL
  • td_os_ver : android.os.Build.VERSION#SDK_INT
  • td_os_type : "Android"

Adding Application Package Version Information to Each Event Automatically

Application package version information is added to each event automatically if you call EnableAutoAppendAppInformation.

TreasureData.Instance.EnableAutoAppendAppInformation();
    :
TreasureData.Instance.AddEvent("unitytbl", "name", "foobar");
// Outputs =>>
//   {"td_app_ver":"1.2.3", "name":"foobar", ... }

It outputs the following column names and values:

iOSAndroid
  • td_app_ver : Core Foundation key CFBundleShortVersionString
  • td_app_ver_num : Core Foundation key CFBundleVersion
  • td_app_ver : android.content.pm.PackageInfo.versionName
  • td_app_ver_num : android.content.pm.PackageInfo.versionCode

Adding Locale Configuration Information to Each Event Automatically

Locale configuration information will be added to each event automatically if you call EnableAutoAppendLocaleInformation.

TreasureData.Instance.EnableAutoAppendLocaleInformation();
    :
td.AddEvent("unitytbl", "name", "foobar");
// Outputs =>>
//   {"td_locale_lang":"en", "name":"foobar", ... }

It outputs the following column names and values:

iOSAndroid
  • td_locale_country : [[NSLocale currentLocale] objectForKey: NSLocaleCountryCode]
  • td_locale_lang : [[NSLocale currentLocale] objectForKey: NSLocaleLanguageCode]
  • td_locale_country : java.util.Locale.getCountry()
  • td_locale_lang : java.util.Locale.getLanguage()

Enable/Disable Debug Log

EnableLogging
TreasureData.EnableLogging();
DisableLogging
TreasureData.DisableLogging();

Error Codes

The TreasureData.Instance.AddEvent and TreasureData.Instance.UploadEvents call the onError delegate method with an errorCode argument. This argument is useful for determining the cause or type of the error. Here are the error code arguments:

Error CodeDescription
init_errorThe initialization failed.
invalid_paramThe parameter passed to the API was invalid
invalid_eventThe event was invalid
data_conversionFailed to convert the data to/from JSON
storage_errorFailed to read/write data in the storage
network_errorFailed to communicate with the server due to network problem
server_responseThe server returned an error response

GDPR Compliance

To support compliance with national and global data privacy requirements such as the European General Data Privacy Regulation, our SDK provides methods that control the collection and tracking of personal data and metadata in applications and websites.

The SDK provides some convenient methods to easily opt-out of tracking the device entirely without having to resort to many cluttered if-else statements:

<treasure_data_instance>.DisableCustomEvent()         // Opt-out of your own events
<treasure_data_instance>.DisableAppLifecycleEvent()  // Opt-out of TD generated events

These can be opted back in by calling EnableCustomEvent() or EnableAppLifecycleEvent(). Note that these settings persist across application restarts. Generally these methods should be called when reflecting your user's choice, not every time the SDK is initialized. By default custom events are enabled and app lifecycle events are disabled.

Use ResetUniqId() to reset the identification of device on subsequent events. td_uuid will be randomized to another value and an extra event is captured with {"td_unity_event": "forget_device_id", "td_uuid": <old_uuid>} to the DefaultTable:

TreasureData.Instance.resetUniqId();

resetUniqId also adds an audit event to the DefaultTable:

{
    "td_unity_event": "forget_device_uuid",
    "td_uuid": old_uuid,
    <configured_additional_parameters...>
}

Customers of Treasure Data must ensure that their usage of the SDK, including its use that collects personal data, complies with the legal agreement that governs access to and use of the Treasure Data service:

Development Mode to Run Application Without Real Devices

This SDK works as a Unity Native Plugin. So you need to run your application with the SDK on a real device especially when you want to run it on iOS platform.

If you want to run your application with the SDK without real devices, you can do that with a special mode for development that emulates the behavior with a pure C# implementation.

Different Behaviors from Normal Mode

In development mode:

  • Buffered events are stored in memory not in persistent storages.
  • When running into an upload failure, buffered events get lost.

Configuration

On PC / iOS / Android / other platforms:

  • Add a symbol TD_SDK_DEV_MODE to Player Settings > Scripting Define Symbols

On Unity Editor:

  • Always enabled. No action required.

Modify Source Code

  • Create SimpleTDClient instance by calling SimpleTDClient.Create() static method in MonoBehaviour#Start method
  • Attach the instance to TreasureData instance
public class TreasureDataExampleScript : MonoBehaviour {
    private static TreasureData td = null;
    // private TreasureData tdOnlyInTheScene = null;
            :
    void Start () {
        td = new TreasureData("YOUR_WRITE_APIKEY");
        /* Optional configurations
            SimpleTDClient.SetDummyAppVersionNumber("77");
            SimpleTDClient.SetDummyBoard("bravo");
            SimpleTDClient.SetDummyBrand("htc_asia_wwe");
            SimpleTDClient.SetDummyDevice("bravo");
            SimpleTDClient.SetDummyDisplay("ERE27");
            SimpleTDClient.SetDummyModel("HTC Desire");
            SimpleTDClient.SetDummyOsVer("2.1");
            SimpleTDClient.SetDummyOsType("android");
            SimpleTDClient.SetDummyLocaleCountry("JP");
            SimpleTDClient.SetDummyLocaleLang("ja");
        */

        // If you want to use a TDClient over scenes, pass `true` to `SimpleTDClient.Create` to prevent it from being removed.
        td.SetSimpleTDClient(SimpleTDClient.Create(true));

        // If you want to use a TDClient only within a scene, don't pass `true` to `SimpleTDClient.Create` so that you can prevent object leaks.
        // tdOnlyInTheScene.SetSimpleTDClient(SimpleTDClient.Create());
            :