解析ツールは、ユーザーがどのようにアプリを使用しているのか、貴重な時間を費やしてまでアプリの機能を改善すべきか、といった問題を考えるときに開発者を助けてくれる存在です。ネイティブプラットホームはたいてい、解析ツールを標準装備していますが、React Nativeなどのクロスプラットホーム開発ツールの場合はどうでしょうか。予想どおり、選択肢はたくさんあります。そして、今回の記事ではSegment.io、Keen.ioを使ってReact Nativeアプリに解析ツールを導入します。
この記事は、React Nativeアプリを作成した経験があるという前提で、アプリのセットアップ方法と解析ツールに関連するコード部分についてのみ説明します(React Nativeアプリを作成した経験がなければ、SitePointの記事を参照してください)。記事ではAndroidを例に書いていますが、iOSでも手順は同じです。また、GitHubで全ソースコードを確認できます。
Segment.ioとKeen.ioについて
Segment.ioはWebサイト、モバイルアプリ、Eメールキャンペーンなどから解析データを集め、データを別のサービスに自動で送ります。Segment.ioは独自のAPIを提供しており、さまざまなプラットホーム(例:モバイルアプリ、Webサイト、Sendgrid、Stripe)で解析データを収集できます。たとえば、Stripeの支払いデータを調査したいときは、Segment.ioのアカウントをStripeに結びつけます。これにより、Stripeで支払いが発生するたびに、自動で支払いを通知するとともに対応するデータを任意のデータウェアハウスに送ります。
Keen.ioはSegment.ioと統合できるサービスの1つで、解析データを収集、検証、可視化するためのAPIを提供します。この記事ではSegment.ioがデータを収集するので、データの収集機能は使用しません。
要約すると、Segment.io APIを使用して解析データを収集し、Keen.ioで解析します。
Segment.ioとKeen.ioのセットアップ
最初にKeen.ioのアカウントを登録します。メールアドレス、会社名、パスワードを入力すると、以下の画面が表示されます。
プロジェクトに合わせた選択肢を選び質問に回答します。回答を終えると、最初のKeen.ioプロジェクトが表示されます。
Keen.ioプロジェクトはそのままにして、ブラウザーの新たなタブを開きSegment.ioのアカウントを登録します。以下の画面が表示されます。
Segment.ioでKeen.ioをセットアップしたいので、ここは飛ばします。ナビゲーションの一番上にある「sources(ソース)」をクリックします。まだソースを追加していないので、以下の画面が表示されます。
「add source(ソースの追加)」をクリックします。一覧表示された各ソースから「Android」を選択して「connect(接続)」を選択します。
ニックネームおよびデータウェアハウスに接続する際に使用するデータベース名を入力します。デフォルトのままでも構いません。今回はデータをKeen.ioのサーバーに保存するため、データウェアハウスの機能は使用しません。
「add source(ソースの追加)」をクリックし完了します。
ソースページに移動すると、新たなソースが一覧に追加されています。新たなソースをクリックし「Write Key(書き込みキー)」をメモします。「Integrations(統合)」をクリックするとSegment.ioに統合できるサービス一覧が表示されます。「KeenIO」をクリックし、表示されたウィンドウの「settings(設定)」タブをクリックします。ここにKeen.ioプロジェクトのプロジェクトIDおよび書き込みキーを入力します。ブラウザーのタブを切り替え、Keen.ioのWebサイトからプロジェクトIDと書き込みキーをコピーします。「Show API Keys(APIキーを表示)」ボタンをクリックすれば書き込みキーを確認できます。
Segment.ioのWebサイトに戻り、コピーしたデータを貼り付け「Save Changes(変更を保存)」をクリックします。これでKeen.ioを有効にするための「Enable Integration(統合を有効にする)」ボタンをクリックできるようになります。
Keen.ioを再度クリックし「Geo IP Addon」と「UserAgent Addon」という2つの詳細設定を有効にします。「Geo IP Addon」を使うとユーザーのIPアドレスに基づいて地理データを収集できるようになります。「UserAgent Addon」を使うとユーザーのデバイスについての詳細情報(たとえば、使用するAndroidデバイスやOSのバージョン)を取得できるようになります。これらをチェックしたら「save changes(変更を保存)」をクリックします。「Read Key(読み出しキー)」が気になるかもしれませんが、Keen.ioからデータを読み出す際に使用するもので、これから作成するサンプルアプリには必要ありません。今回は、アプリを通して得られたデータをKeen.ioのダッシュボード上で操作します。
アプリの概要
本記事のために、簡単なギャラリーアプリを作成しました。このアプリを使って、React Nativeに解析ツールを実装する方法を説明します。アプリは2つの画面を持っています。コレクション一覧画面と、コレクション閲覧画面です。次がコレクション一覧画面です。
下がコレクション閲覧画面です。
コレクション一覧画面は、想像上のユーザーによって追加された各コレクションを一覧表示します。「想像上の」という点に留意してください。アプリは単純に作ってあり、使用するデータはすべてコードに直接埋め込まれています。また、アプリを使用する各ユーザーを識別するためのログイン機能もありません。つまり、ユーザーを識別するためには、デバイス内にある固有の識別子を使用する必要があります。
コレクション閲覧画面では各写真につき3つのボタンがあります。アイコンの形から機能が予想できるかもしれませんが、左からお気に入り、ブックマーク、共有です。これら3つのボタンはアイコンのようには動作しません。ボタンの目的は単に解析データを記録することなので、ユーザーに対しては操作が確認されたことを通知するだけです。
アプリのセットアップ
本記事を執筆している時点では、React Nativeのバージョンは0.29です(日本版編注:本記事のオリジナルは2016年8月に執筆された)。もしこの記事を読んでいる時点でバージョンが異なる場合、デモを確実に動作させるには次のいずれかの方法を試してください。1つ目は、Githubリポジトリのクローンを作成後、Segment.ioから取得した書き込みキーを使ってconfig.jsを更新し、アプリを実行する方法です。
2つ目の方法は、自分でセットアップしたい場合です。rninintをインストールしReactive Nativeプロジェクトを新たに初期化(バージョンは0.29)します。そしてGithubリポジトリから以下のファイルとフォルダーをコピーします。
- index.android.js
- config.js
- data.js
- pages
- package.json
完了後、ターミナルでnpm installを実行して依存オブジェクトをインストールし、Segment.ioから取得した書き込みキーを使ってconfig.jsを更新します。さらにインストールされたパッケージが動作するように、Androidソースファイルを更新します。
パッケージのリンク
package.jsonには、ReactとReact Nativeのほかに以下のパッケージが含まれています。
これらのパッケージを使用するには、パッケージとAndroidプロジェクトをリンクする必要があります。android/settings.gradleファイルを開き、以下を追加します。
include ':react-native-device-info'
project(':react-native-device-info').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-device-info/android')
include ':react-native-analytics'
project(':react-native-analytics').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-analytics/android')
include ':react-native-vector-icons'
project(':react-native-vector-icons').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vector-icons/android')
このファイルでは各サードパーティ製パッケージのインストール先へのパスを指定しています。settings.gradleファイルの内容はリンク先で確認できます。
android/app/build.gradleファイルを開きapply plugin: "com.android.application"のあとに以下を追加します。
project.ext.vectoricons = [
iconFontNames: [ 'FontAwesome.ttf' ] // Name of the font files you want to copy
]
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
追加したコードにより、React Native Vector Iconsパッケージで使用するフォントファイルとリンクできます。今回は、FontAwesomeのみ使用するためiconFontNames配列にはこのフォントだけを追加します。
同じファイル内でdependenciesオブジェクトを探し、以下が含まれていることを確認します。
compile project(':react-native-device-info')
compile project(':react-native-analytics')
compile fileTree(dir: "libs", include: ["*.jar"])
compile "com.android.support:appcompat-v7:23.0.1"
compile "com.facebook.react:react-native:+" // From node_modules
compile project(':react-native-vector-icons')
このコードにより、アプリをコンパイルする際にすべてのパッケージを追加できるようになります。build.gradleファイルの内容はリンク先で確認できます。
android/app/src/main/java/com/NAME-OF-YOUR-REACT-NATIVE-PROJECT/MainApplication.javaを開き、Java Listユーティリティをインポートしている箇所のあとに以下を追加します。
import com.oblador.vectoricons.VectorIconsPackage;
import com.smore.RNSegmentIOAnalytics.RNSegmentIOAnalyticsPackage;
import com.learnium.RNDeviceInfo.RNDeviceInfo;
続いて、Reactメインパッケージのあとに以下を追加します。
new RNSegmentIOAnalyticsPackage(),
new VectorIconsPackage(),
new RNDeviceInfo()
このようにして、React Native Analyticsパッケージ、Vector Iconsパッケージ、Device Infoパッケージを初期化します。
MainApplication.javaファイルの内容はリンク先で確認できます。
コードの説明
デモ用アプリのセットアップ方法を確認したので、次はコードを検証してデータをどのように収集するか説明します。
最初にindex.android.jsを開きます。最初の数行で必要なパッケージをインポートしています。DeviceInfoを使用しユーザーが使用するデバイスの情報を取得します。デバイスの情報は、固有デバイスID、メーカー、モデル、バージョン番号、ビルド番号などです。
import DeviceInfo from 'react-native-device-info';
import config from './config';
import Analytics from 'react-native-analytics';
アプリにはログインシステムがないため、固有デバイスIDで各ユーザーを識別します。componentWillMount関数には、setup、identifyというAnalyticsパッケージのメソッドが2つあります。setupは解析データを保存するためのプロジェクトをセットアップします。Segment.ioの書き込みキーおよびフラッシュの設定を引数として関数に渡します。フラッシュとは、イベントをいつ送信するか設定するための機能です。1に設定すると、たとえば、ユーザーがアカウントを作成するなどのイベントが発生するたびに送信します。
このように特定の動作を記録するように指定した場合、動作に関するデータは自動的にサーバーへ送られます。今回は効率良くテストするため、config.jsで1に設定しています。実際のアプリ作成では、20かそれ以上に設定しておけば、それぞれの動作をキューに蓄え設定したイベント数が記録されたときにだけサーバーに送信できます。
componentWillMount() {
Analytics.setup(config.segmentIOWriteKey, config.flushSetting);
Analytics.identify(DeviceInfo.getUniqueID(), {
device_manufacturer: DeviceInfo.getManufacturer(),
device_model: DeviceInfo.getModel(),
system_name: DeviceInfo.getSystemName(),
system_version: DeviceInfo.getSystemVersion()
});
}
もう1つの関数identifyはDeviceInfoパッケージのgetUniqueIDメソッドでユーザーを識別します。また、使用されたデバイスの情報を第2引数のオブジェクトとして受け取り、記録します。この情報は、ユーザーがアプリにアクセスするためにどのようなデバイスを使用したかを知りたい場合に役立ちます。
注意:アプリはデバイスIDを使用してユーザーを識別しているため、あるユーザーがどのデバイスを使用しているかは特定できないことに注意してください。実際は同じユーザーでも、別のデバイスを使用している場合は新たなユーザーとして区別されます。
次にpages/CollectionList.jsを説明します。このページはコレクションの一覧を表示します。今回の場合、動物の一覧です。表示するデータはdata.jsファイルにあります。コンポーネントをマウントする前に、screenメソッドを呼び出しています。このメソッドはユーザーがアクセスしたページや画面を記録します。今回はコレクション一覧画面が1つしかないため、値はハードコーディングされています。
たとえば「生物」など、より広い区分で一覧表示する画面がある場合は、下のようなハードコーディングされた値の代わりにデータをメソッドに渡すことでページ情報を取得できます。screenメソッドはページ名を第1引数として受け取ります。またオプションとして、任意の追加データを含むオブジェクトを受け取ります。
componentWillMount() {
//...
Analytics.screen("Animals", {"description": "A list containing different animals"});
}
ユーザーがコレクション一覧画面の項目を1つタップすると、項目内に追加された写真が表示されます。これらの写真はpages/Item.jsファイルによって表示されます。先にも説明したように、それぞれの写真の下には3つのボタンがあり、写真に対するユーザーの操作を記録します。最初は、ユーザーが特定の画面にアクセスしたことを記録するコードです。コレクション一覧画面からpropsとして渡されたitemオブジェクトにより画面名を取得します。
componentWillMount() {
//...
Analytics.screen(this.props.item.title);
}
次はユーザーがお気に入り、ブックマーク、共有ボタンをタップしたときに呼び出される関数です。動作を記録するためにtrack関数を使用します。この関数は動作名を受け取り、またオプションとして任意の追加データを含むオブジェクトを受け取ります。今回は、写真が属するコレクション名、写真の表題、写真のURLを渡しています。各動作に名前を付ける際には、過去形と名詞を使用するのが最適です。たとえば、Generated Report(作成されたレポート)、Checked out Cart(支払いを終えた買い物かご)、Watched Video(視聴完了したビデオ)のようにします。
_favorite(photo) {
Analytics.track("Favorited Photo", {
gallery: this.props.item.title,
caption: photo.caption,
url: photo.url
});
alert('favorited!');
}
_bookmark(photo) {
Analytics.track("Bookmarked Photo", {
gallery: this.props.item.title,
caption: photo.caption,
url: photo.url
});
alert('bookmarked!');
}
_share(photo) {
Analytics.track("Shared Photo", {
gallery: this.props.item.title,
caption: photo.caption,
url: photo.url
});
alert('shared!');
}
データの解析
アプリをデバイスまたはエミュレータで実行し、各ページにアクセスして写真を操作し、データを収集します。
Keen.ioのWebサイトを開き、前もって作成しておいたプロジェクトをクリックします。
クリック後のページで「explorer(エクスプローラー)」タブをクリックすると次の画面が表示されます。
これがKeen.ioのエクスプローラーで、さまざまなクエリを実行し希望するデータを得られます。たとえば、ある写真を気に入ったユーザーの総数を知りたい場合は「analysis type(解析タイプ)」を「count(集計)」に、「event collection(収集するイベント)」を「Favorited Photo(お気に入りに選ばれた写真)」に設定し「Run Query(クエリの実行)」ボタンを押して実行します。
特定のフィールドを使用して集計をグループ化したい場合は「Group By(グループ化)」セクションにあるフィールドを選択してからクエリを実行します。次の例では「gallery(ギャラリー)」を選択し、結果をコレクションごとにグループ化しました。
「extraction(抽出)」クエリも実行できます。
これはリレーショナルデータベースシステムのSELECT *と同等です。データをCSVファイルにエクスポートしたいときはこの機能を使用します。
「select unique(一意選択)」という分析タイプもあります。使用すると特定のフィールドの値を一意に(重複なしに)取り出せます。次の例では「Favorited Photo(お気に入りに選ばれた写真)」イベントが発生したすべての表題を一意に取り出しています。
フィルターを使用すれば、データを特定のフィールドでフィルタリングできます。使用するには、最初にFilters(フィルター)セクションをクリックし、続いてフィルターとして使いたいフィールドを選択します。次の例では「gallery(ギャラリー)」フィールドを選択し、値は「Cats(猫)」を設定しています。
設定したあと、グループ化フィールドとして「caption(表題)」フィールドを選択します。猫のコレクションでそれぞれの写真をブックマークしたユーザーがどれくらいいるか表示されます。
最後に「preview collections(コレクションのプレビュー)」のリンクをクリックすると各デバイスから送信された生データを確認できます。
以下が得られたデータのサンプルです。
[
{
"parsed_user_agent": {
"device": {
"family": "Samsung SM-T113NU"
},
"os": {
"major": "4",
"patch_minor": null,
"minor": "4",
"family": "Android",
"patch": "4"
},
"browser": {
"major": "4",
"minor": "4",
"family": "Android",
"patch": "4"
}
},
"keen": {
"timestamp": "2016-07-15T06:00:18.986Z",
"created_at": "2016-07-15T06:00:19.236Z",
"id": "xxx"
},
"url": "https://pixabay.com/static/uploads/photo/2016/05/31/16/04/humboldt-penguin-1427228_640.jpg",
"userId": "xxx",
"caption": "swimming penguin",
"user_agent": "Dalvik/1.6.0 (Linux; U; Android 4.4.4; SM-T113NU Build/KTU84P)",
"ip_geo_info": {
"province": null,
"city": null,
"postal_code": null,
"continent": "Asia",
"country": "Philippines"
},
"ip_address": "112.xxx.xx.xx",
"gallery": "Penguins",
"page_url": "https://pixabay.com/static/uploads/photo/2016/05/31/16/04/humboldt-penguin-1427228_640.jpg"
}
]
上のように、保存するように指定したデータやそのほかの情報が含まれています。たとえば、デバイス情報、IPアドレス、地理情報、keen.idとuserIdといったユーザー情報などです。keen.idはKeen.ioがこのイベント用に生成した固有IDです。userIdは本記事で追加した固有デバイスIDです。
この記事の解析
以上です! この記事では、React Nativeアプリに解析ツールを実装する方法としてSegment.ioとKeen.ioを説明してきました。記事を通して、アプリに解析ツールを実装するための知識を伝えられていれば幸いです。
(原文:Adding Analytics to a React Native App)
[翻訳:薮田佳佑/編集:Livit]