こんにちは。TreasureDataの駒津です。初Qiita投稿となりますが、今回は Treasure Data Advent Calendar 2014 の22日目の記事として、TreasureData (Android|iOS|Unity) SDKについて紹介したいと思います。
TreasureDataが提供しているSmartphone向けSDK
Treasure Dataのデータインポート方法一覧 でも紹介されている通り、現在TreasureDataにデータを集める手段は数種類あります。その中でSmartphone向けでは以下のSDKが提供されています。
- Android SDK
- iOS SDK
- Unity SDK
いずれも各SDKからTreasureDataに直接データをインポートするため、ユーザー側でサーバーを準備する手間が不要となります。
Smartphone向けSDKの機能
Smartphone向けSDKの機能としては以下のものがあります。
- アプリ内で発生したイベントを登録(クライアント側でバッファリング) (
addEvent
/addEventWithCallback
) - バッファリングされたデータは任意の共通鍵にて自動的に暗号・復号化が可能 (
initializeEncryptionKey
, default:disable) - バッファリングされたイベント群をTDにアップロード(アップロード成功時のみバッファをクリアするためデータロストを防止) (
uploadEvents
/uploadEventsWithCallback
) - アップロード失敗時には一定回数のリトライ(Exponential backoff)を実施 (
enableRetryUploading
/disableRetryUploading
, default:enable) - アップロードデータは自動的に圧縮され転送データ量を1/8程度に低減 (
enableEventCompression
/diableEventCompression
, default:enable) - イベント登録・アップロード処理の成否に応じて呼ばれるコールバック処理を登録可能 (
addEventWithCallback
/uploadEventsWithCallback
) - SDK内部にてデバイスごとに一意となるIDを生成。当該IDを各イベントに自動付与できるため、デバイスごとの集計が容易に (
enableAutoAppendUniqId
/disableAutoAppendUniqId
, default:disable) - OSのバージョンやデバイスの種類を各イベントに自動付与可能 (
enableAutoAppendModelInformation
/disableAutoAppendModelInformation
, default:disable) - セッションの開始、終了ごとにセッションIDが生成可能。各イベントに自動付与できるため、アプリで発生する一連のイベント群ごとに集計できる (
startSession
/endSession
) - SDKが初回起動済みかどうかの状態を管理しており、アプリの初回起動判定に利用することが可能 (
isFirstRun
/clearFirstRun
) - サーバー側でイベントの重複排除を行っているためアップロードが複数回行われてもデータの重複を防止(現在、1日間の重複排除を実施)
各機能説明の末尾に記載してある文字列は、対応するSDKのAPI名(具体的には TreasureData
クラスのメソッド名)です。
また、Smartphone向けSDKでは、登録するイベントについてデータベースとテーブルを指定するようになっています。これらはインポート先となるTreasureDataサービス上のデータベースとテーブルと対応しています。
一例として、enableAutoAppendUniqId
, enableAutoAppendModelInformation
を有効にし、 startSession
, endSession
を利用した際のテストデータの一部をTD上で確認すると以下のようになります。
書き込み専用ユーザーおよびAPI keyの利用
TreasureDataではデータのインポートやクエリの発行時の認証のためにAPI keyを用いますが、Smartphone向けSDK(JS SDKも)を利用する場合は、以下の手順を推奨します。
- Smartphone向けSDKからのインポート用にTDにデータベースを作成
- 上記で作成したデータベースにのみアクセス可能なユーザーをTDのアカウントに追加
- ユーザーの追加は https://console.treasuredata.com/users から
Add Team Member
をご利用ください - 上記で追加したユーザーの書き込み専用API keyを作成
- 上記で作成した書き込み専用API keyをSmartphone向けSDKにて利用
なお、書き込み専用API keyの発行は https://console.treasuredata.com/ 画面の右上の My Profile
を押下した後、API Keys
メニューにパスワードを入れることで発行可能になります(下記画像)。
Android SDKの概要とインストール方法
現在の最新バージョンは0.1.6です。0.1.5に比べるとバグフィックスや新機能(セッション、デバイス固有のID、OSバージョン等の付与設定)が追加されています。古いバージョンをご利用の方は是非最新バージョンをご利用ください。
Mavenをご利用の場合は以下のdirectiveをpom.xmlに追加してください。
<dependency>
<groupId>com.treasuredata</groupId>
<artifactId>td-android-sdk</artifactId>
<version>0.1.6</version>
</dependency>
直接jarを利用したい場合は以下からダウンロードしてください。
また、TDへのアップロード時にはインターネットへの接続が必須となりますので以下のpermissionの追加が必要となります。
<uses-permission android:name="android.permission.INTERNET"/>
Android SDKについては [TreasureData + Android SDK] (http://qiita.com/akito1986/items/b919ac4fe89ce6118311) の記事で非常にわかりやすく説明されています。
iOS SDKの概要とインストール方法
現在の最新バージョンは0.1.6です。Android SDKと同様、0.1.5に比べるとバグフィックスや新機能(セッション、デバイス固有のID、OSバージョン等の付与設定)が追加されています。古いバージョンをご利用の方は是非最新バージョンをご利用ください。
CocoaPods でのインストールとなりますので、CocoaPodsインストール未済の場合は以下のようにインストールが必要となります。
$ gem install cocoapods
iOSアプリプロジェクト直下のPodfileに以下を追記(ファイルが無ければ作成)。
pod 'TreasureData-iOS-SDK', '= 0.1.6'
その後、pod install
コマンドを実行し、更新された (ProjectName).xcworkspace を開いてください。
$ pod install
アプリ終了時にアップロードする際の注意点
アプリの終了のタイミングでTDへのアップロードを行いたい場合、UIApplicationDelegate
の applicationDidEnterBackground
内で、uploadEvents
系のメソッド(詳細は後述)を呼び出すケースがあるかと思いますが、その場合は以下のように UIApplication
の beginBackgroundTaskWithExpirationHandler
を呼んで long-running background taskを開始しておいてください。
__block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
[[TreasureData sharedInstance] uploadEventsWithCallback:^() {
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
onError:^(NSString *code, NSString *msg) {
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
以前、https://github.com/treasure-data/td-ios-sdk および http://docs.treasuredata.com/articles/ios-sdk では beginBackgroundTaskWithExpirationHandler
を使わないコード例が記載されていた時期がありました。そのコード例をそのまま使うとアプリ終了時のアップロードに失敗する場合があるため、是非最新のコード例を参照ください。
Unity SDKの概要とインストール方法
Unity SDKは、内部的には前述のAndroidおよびiOS SDKをNative pluginとして組み込み、Unity側ではC#で橋渡しをする処理を実装し各SDKを利用しています。
Unity SDKは
https://github.com/treasure-data/td-unity-sdk-package にてunitypackageとしてリリースしています。現在の最新版は0.1.2ですが、これはまだ
Android/iOS SDKともに最新版を組み込んでいないため、今週リリース予定(...!)である次の0.1.3を待ったほうが良いかと思います。
0.1.3がリリースされました。https://github.com/treasure-data/td-unity-sdk-package/blob/master/TD-Unity-SDK-0.1.3.unitypackage 前述のAndroid/iOS SDK 0.1.6 を組み込んでいますので、古いバージョンをお使いの方は是非最新版をお試しください。
UnityプロジェクトにSDKをインストールする際は、以下の手順が必要となります。
- https://github.com/treasure-data/td-unity-sdk-package から https://github.com/treasure-data/td-unity-sdk-package/blob/master/TD-Unity-SDK-x.x.x.unitypackage をダウンロード
- Unityプロジェクト上で
Assets -> Import Package -> Custom Package
を選択し、当該unitypackageをインポート
各SDKに関する詳細
ここまで、Smartphone向けSDKに関する概要を説明しましたが、より詳細な情報については以下のリンクが有用かと思います。
- Android SDK
- 詳細情報
- サンプルプロジェクト
- iOS SDK
- 詳細情報
- サンプルプロジェクト
- Unity SDK
- 詳細情報
- サンプルプロジェクト
サンプルコードを例にした説明
最後にAndroid SDKを利用したサンプルコードを紹介したいと思います。細かめなコメントを含んでいるので参考になれば幸いです。
package com.treasuredata.android.exampleapp;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.util.Pair;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import com.treasuredata.android.TDCallback;
import com.treasuredata.android.TreasureData;
public class MainActivity extends Activity {
private static final String TAG = MainActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// このAPIにてインポート先のエンドポイントを変更できます.
// この例は "Yahoo!ビッグデータインサイト" を利用する際の例です.
// TreasureData.initializeApiEndpoint("https://mobile-ybi.jp-east.idcfcloud.com");
// デフォルトのAPIキーの登録が可能です
// TreasureData.initializeDefaultApiKey("your_default_api_key");
// デバッグのためLoggingを有効に
TreasureData.enableLogging();
// バッファリング中の暗号化を有効にし、共通鍵の元となるフレーズを登録
TreasureData.initializeEncryptionKey("hello world");
// データ転送時の圧縮を無効にできます(初期状態は有効)
// TreasureData.disableEventCompression();
// アプリケーション内で共有するインスタンスを初期化
// API keyは各インスタンスを生成するタイミングでも指定できます
TreasureData.initializeSharedInstance(this, "your_default_api_key");
// 上記で初期化した共有インスタンスに対し各種設定を行います
// - デバッグモードを有効にしエラー発生時に例外を発生させるように変更
// TreasureData.sharedInstance().setDebugMode(true);
// - SDK内部においてデバイスごとに一意なIDを、各イベントに自動的に付与します
TreasureData.sharedInstance().enableAutoAppendUniqId();
// - OSのバージョンやデバイス名などを、各イベントに自動的に付与します
TreasureData.sharedInstance().enableAutoAppendModelInformation();
// - デフォルトのデータベースを指定することで以降はテーブル名のみの指定が可能となります
TreasureData.sharedInstance().setDefaultDatabase("testdb");
// - セッションを開始します
// このタイミングで "td_session_event":"start" というイベントが追加されます
TreasureData.sharedInstance().startSession("demotbl");
// - アップロード時のリトライ機能を無効にします (初期状態は有効)
// TreasureData.sharedInstance().disableAutoRetryUploading();
// SDKが初回起動状態かどうかを判定します
if (TreasureData.sharedInstance().isFirstRun(this)) {
// イベントを登録します. 処理成否に応じたコールバックが呼ばれます
TreasureData.sharedInstance().addEventWithCallback("demotbl", "first_run", true, new TDCallback() {
@Override
public void onSuccess() {
// 登録処理が成功した場合には、SDK初回起動フラグをクリアします (以降の isFirstRun() は false を返します)
TreasureData.sharedInstance().clearFirstRun(MainActivity.this);
}
@Override
public void onError(String errorCode, Exception e) {
Log.w(TAG, "TreasureData.addEvent:onError errorCode=" + errorCode + ", ex=" + e);
}
});
}
findViewById(R.id.image).setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent ev) {
// イベントの登録を行います
// ここでは R.id.image という View をタッチした際のイベントを
// 簡単のため文字列化して登録していますが、実際は Map<String, Object> に変換して
// addEvent() にて登録したほうが、後のTD上での集計がやりやすいと思います
TreasureData.sharedInstance().addEvent("demotbl", "image", ev.toString());
return false;
}
});
findViewById(R.id.upload).setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
// addEvent()にてバッファリングされたイベント群をアップロードします (処理成否のコールバック付き)
// ここでは R.id.upload という View がタッチされたタイミングで処理を実行しています
TreasureData.sharedInstance().uploadEventsWithCallback(new TDCallback() {
@Override
public void onSuccess() {
Log.d(TAG, "TreasureData.uploadEvents:onSuccess");
}
@Override
public void onError(String errorCode, Exception e) {
Log.w(TAG, "TreasureData.uploadEvents:onError errorCode=" + errorCode + ", ex=" + e);
}
});
return false;
}
});
}
@Override
protected void onDestroy() {
// セッションを終了します
// このタイミングで "td_session_event":"end" というイベントが追加されます
TreasureData.sharedInstance().endSession("demotbl");
// バッファリングされたイベント群をアップロードします
// ここでは MainActivity の終了のタイミングで処理を実行しています
TreasureData.sharedInstance().uploadEvents();
super.onDestroy();
}
}
Android/iOS SDKのv0.1.6のリリースがこの記事に間に合って少しほっとしています。
なお、Unity SDK v0.1.3のリリースのタイミングで本記事を更新する予定です。