GoogleAnalyticsを昔から利用しているアプリでの計測方法の紹介

Google AnalyticsはもともとはWebサービスの計測ツールとして出ていましたが、ネイティブアプリの計測もサポートしています。

私がアプリ開発を始めたとき(約3年ほど前)はGoogle Analytics一択だった気がします。(違かったらすみません)

今現在ではFirebase AnalyticsMixpannelなどイベントログベースのネイティブアプリに特化した計測ツールが有名ですが、未だにGoogle Analyticsから離れられないサービスがたくさんあるかと思います。

例えば

  • 長期的にサービスを運用していて過去のデータを捨てられない
  • ディレクターやプロデューサーがGoogle Analyticsでの分析方法のノウハウが豊富
  • サービスの指標がGoogle Analyticsベースで作成されている

など様々な原因があるかと思います。

なのでこの記事ではGoogle Analyticsで計測する上でよく使用される「用語」と「実装方法」を紹介していきたいと思います。

この記事で

  • GoogleAnalytics、知ってはいるけど使ったことない
  • Webは知ってるけどアプリでの計測は知らない
  • 計測方法がわからなくて困っている

といった問題の解決のきっかけを作れたら幸いです。

紹介する計測の用語

以下の計測周りを紹介していきます。

  • ユーザー属性
  • スクリーン
  • イベント
  • 課金(Eコマース)
  • カスタムディメンション

実装環境

今回実装した環境は以下になります。

Xcode
9.0
iOS
iOS9以上
Swift
4
Cocoa Pods
1.3.1

使えるようになるまでの実装

すでにGoogleAnalyticsが使えているようであれば、いらない部分になりますのでスキップしてもらえればと思います。

ライブラリのインストール方法

Google AnalyticsのiOSのSDKはCocoa Podsで公開されているのでそちらを使いたいと思います。

$ bundle exec pod --version
1.3.1
$ bundle exec pod search GoogleAnalytics
-> GoogleAnalytics (3.17.0)
   Google Analytics - measure your app performance
   pod 'GoogleAnalytics', '~> 3.17.0'
   - Homepage: https://www.google.com/analytics
   - Source:   https://www.gstatic.com/cpdc/5cd71dd2f756bb01/GoogleAnalytics-3.17.0.tar.gz
   - Versions: 3.17.0, 3.16.0, 3.14.0, 3.13.0, 3.12.0 [cocoapods repo]

のでPodfileに以下を追加して、bundle exec pod installをしてください。

# Podfile
pod 'GoogleAnalytics', '~> 3.17.0'

GoogleAnalyticsObjective-Cで出来ているのでBridging Headerでimportします。

以下を追加してパスを指定してください。

/// GoogleAnalytics
#import <GoogleAnalytics/GAI.h>
#import <GoogleAnalytics/GAIFields.h>
#import <GoogleAnalytics/GAIDictionaryBuilder.h>
#import <GoogleAnalytics/GAIEcommerceFields.h>

これでビルドが通れば使えるようになります。

初期設定

初期化します。

private let trackingID: String = ""

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        // TrackingIDの指定
        GAI.sharedInstance().tracker(withTrackingId: trackingID)
        // イベント等を送る間隔
        // 短いほど素早く送るがその分負荷かかります。
        // 秒
        GAI.sharedInstance().dispatchInterval = 30

        // ログレベル
        // リリースビルド時は邪魔になるので、適当なものを指定してください
        GAI.sharedInstance().logger.logLevel = .verbose

        // Google Analyticsでクラッシュログをトラッキングするかのフラグです
        // いらない場合はfalseを指定してください
        GAI.sharedInstance().trackUncaughtExceptions = true

        return true
    }

    ~ 省略 ~
}

これで準備完了です。

今回実装したソースコードは以下に公開していますので、参考にしていただけたら幸いです。

それでは紹介していきたいと思います。

ユーザー属性

最初にGoogle Analyticsがすでに情報として持っているユーザー属性の活用方法を紹介します。

知れること

Google Analyticsが収集している個人の属性を参照することができるようになります。

参照できるようになる属性は

  • 年齢(18 ~ 24歳みたいな範囲)
  • 性別(男性 or 女性)
  • インタレスト カテゴリ
    • 何に興味があるかなど…

これを利用してセグメントを切ることが出来るので以下のようなことが知れるようになります。

  • 25 ~ 34歳の男性のリテンション
  • 18 ~ 24歳の女性が実行したイベント

また利用者のグラフも確認できるので、サービスがどの年齢や性別の人たちに多く使われているかの情報も確認することができます。

iOSでは「個人情報をアプリで取得してサーバーに保存して利用する」という行為をするためにしなければならないことが多いので、計測のみで知りたいというレベルであれば、これを導入するべきだと思います。

問題点

実際に使用するためにユーザー(端末)のIDFAを利用するため、広告を実装していないアプリは利用できない可能性があります。

広告を実装しないアプリを作成したことがないので絶対出来ないとは断定出来ません

またIDFAを取得するためにAdSupport.frameworkを使用します。

では実際に計測する手段を紹介します。

計測方法

まずはGoogle Analyticsの管理画面でスイッチを押します。

アカウント > プロパティの中にあるプロパティ設定 > ユーザー属性レポートとインタレスト カテゴリ レポートの有効化のスイッチをONにします。

ScreenShot1

これをしないと実装しても反映されないので気をつけてください。

CocoaPodsで必要なライブラリをインストール

次にCocoaPodsでさらに必要になるライブラリをインストールします。

$ bundle exec pod search GoogleIDFASupport
-> GoogleIDFASupport (3.14.0)
   Google IDFA Support provides IDFA to Google Analytics and Google Tag Manager
   pod 'GoogleIDFASupport', '~> 3.14.0'
   - Homepage: https://www.google.com/tagmanager
   - Source:   https://www.gstatic.com/cpdc/c45591522c4ba5b8-GoogleIDFASupport-3.14.0.tar.gz
   - Versions: 3.14.0, 3.12.0 [cocoapods repo]

GoogleIDFASupportをインストールします。

# Gemfile
pod 'GoogleIDFASupport', '~> 3.14.0'

AdSupport.frameworkを追加します。

ScreenShot2

これをしたら

ScreenShot3

こうなります。

これで準備完了です。

取得方法

GAITrackerを使う前にallowIDFACollectiontrueを入れれば計測時にSDK側で勝手に集計してくれます。

extension ViewController {

    func tracker() -> GAITracker? {
        let tracker = GAI.sharedInstance().defaultTracker
        tracker?.allowIDFACollection = true
        return tracker
    }

}

この処理をした後にスクリーンなり、イベントなりを送ることでユーザー情報を参照することが出来ます。

それでは次からサービス独自の計測の仕方を紹介していきます。

スクリーン

スクリーンはGoogle AnalyticsのSDKのチュートリアルでも書かれている、初歩的な計測になります。

スクリーン名は実装時に好きな名前をつけられるので適切な名前を送る様にしましょう。

知れること

  • ユーザーの画面別滞在時間
  • ユーザーの行動フロー(画面遷移)
  • ユーザーの画面別離脱率(数)
  • ユーザーの画面別滞在率(数)

ということがわかるようになります。

サービスでよく見られている画面や、離脱率がすごい多い画面などがわかります。

またスクリーンを計測することでアクティブユーザーやDAU(Daily Active User)、リテンション等も一緒に解析してくれます。

計測方法

計測する処理を実装する手段は2つあります。

  • GoogleAnalyticsで用意されているGAITrackedViewControllerを継承したViewControllerを使う
  • 自分でscreenを送信する

適材適所で実装していただければと思います。

GAITrackedViewControllerを継承した計測方法

GAITrackedViewControllerを継承します。

class ViewController: GAITrackedViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        // GAITrackedViewControllerのtrackerは`GAI.sharedInstance().defaultTracker`が使用されます
        // 独自のものを使う場合は指定する必要があります
        self.tracker = self.tracker()

        // スクリーン名の指定
        // viewDidAppearのタイミングで送信されるので、それまでにセットしておく
        // screenNameがnilの場合は送信されない
        self.screenName = "トップ"
    }

}

allowIDFASupportやこの後紹介するカスタムディメンションを使う場合は必ずtrackerにGAITrackerを渡しましょう。

デフォルトはGAI.sharedInstance().defaultTrackerです。

自分でscreenを送信する

以下のように送信します。


class ViewController: UIViewController { override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) sendScreen() } } extension ViewController { func sendScreen() { let tracker = self.tracker() tracker?.set(kGAIScreenName, value: "トップ") let params = GAIDictionaryBuilder.createScreenView().build() as! [AnyHashable: Any] tracker?.send(params) } }

GoogleAnalyticsObjective-Cで作られているのもあってGAIDictionaryBuilderbuild()NSDictionaryを返してきます。

なので、[AnyHashable: Any]にキャストしてGAITracker.send(_: [AnyHashable: Any]!)を使用して送信します。

うまく送信できれば以下のようなログが流れます。

VERBOSE: GoogleAnalytics 3.17 -[GAIBatchingDispatcher persist:] (GAIBatchingDispatcher.m:518): Saved hit: {
    parameters =     {
        // いくつか省略してます
        "&aid" = "com.example.SampleGoogleAnalytics";
        "&an" = SampleGoogleAnalytics;
        "&ate" = 1;
        "&av" = "1.0.0";
        "&t" = screenview;
        gaiVersion = "3.17";
    };
    timestamp = "{時間}";
}

あとは少し放置するとGAIBatchingDispatcherなるものがログに出力されて送信処理が走ります。

Google Analyticsのリアルタイムで確認できるかと思います。

ScreenShot4

リアルタイムはデバッグでとても使うので、覚えておいて損はないと思います。

次はイベント計測を紹介します。

イベント

ユーザーが行った動作を計測するのがイベントになります。

スクリーンと違い、計測に好きな情報を追加できたり、カテゴライズしてまとめることなどが出来ます。

知れること

そのままですが、ユーザーが何をしたかを知ることが出来ます。

またGoogle Analyticsのイベントは以下のように定められています。

  • イベントカテゴリ
  • イベントアクション
  • イベントラベル

以下のような関係値になります

Event
├── Category1
│   ├── Action1
│   │   ├── Label1
│   │   └── Label2
│   ├── Action2
│   │   └── Label
│   └── Action3
│       ├── Label1
│       ├── Label2
│       └── Label3
├── Category2
│   └── Action
│       ├── Label1
│       └── Label2
└── Category3
    ├── Action1
    │   └── Label
    └── Action2
        └── Label

カテゴリの中でアクションを定めて、必要なLabelをつけるという流れになります。

画面ごとにカテゴリを定めて、その画面の中のアクションを分けるという計測も可能ですし、大きくアプリの挙動をカテゴリで定めて、その中の細かいアクションを分けるという計測も可能です。

またカテゴリ、アクション、ラベルごとにイベント数とユニークイベント(ユーザー)数が計測出来ます。

例えばECサイトで一覧画面で商品が選択されて詳細画面へ遷移したというイベントを計測する際に

カテゴリ
商品選択
アクション
選択された商品名
ラベル
選択された画面の名前

としたらこのイベントだけで

  • ユーザーの全商品選択数
    • 全ユーザーの○%が一覧から詳細画面へ遷移したかわかる
  • ある商品の選択された数
    • 一番選ばれている(興味を持たれた)商品がわかる
  • ある商品の選択された画面の割合
    • ある商品がどこの画面にあると選ばれやすいのかがわかる

という様な計測ができる様になります。

(上記は例で私自身ECサイト運営したことないので完全な妄想です…。)

それでは計測方法を紹介していきます。

計測方法

イベントの計測は自分でごりっとソースコードを書きます。


extension ViewController { func sendEvent(category: String, action: String, label: String) { let tracker = self.tracker() let params = GAIDictionaryBuilder.createEvent(withCategory: category, action: action, label: label, value: nil).build() as! [AnyHashable: Any] tracker?.send(params) } }

上記のように実装して、送信します。

例えばボタンを押されたらタップイベントを送る場合は以下のようになります。

extension ViewController {

    @IBAction func tapButton(_ button: UIButton) {
        sendEvent(category: "TOP", action: "タップ", label: "ボタン")
    }

    func sendEvent(category: String, action: String, label: String) {
        let tracker = self.tracker()
        let params = GAIDictionaryBuilder.createEvent(withCategory: category, action: action, label: label, value: nil).build() as! [AnyHashable: Any]
        tracker?.send(params)
    }

}

すると以下のようにログが流れます。

VERBOSE: GoogleAnalytics 3.17 -[GAIBatchingDispatcher persist:] (GAIBatchingDispatcher.m:518): Saved hit: {
    parameters =     {
        // いくつか省略してます
        "&aid" = "com.example.SampleGoogleAnalytics";
        "&an" = SampleGoogleAnalytics;
        "&ate" = 1;
        "&av" = "1.0.0";
        "&t" = event;
        gaiVersion = "3.17";
    };
    timestamp = "{時間}";
}

先ほどのスクリーンの時のログの"$t"の値はscreenviewでしたが、今回はeventとなっているのがわかるかと思います。

リアルタイムでも以下のように表示されました。

ScreenShot5

これから掘り下げるとラベルが出てきたりします。

続いてイベントとは別に処理しなければいけない、アプリ内課金の計測方法を紹介します。

課金(Eコマース)

アプリサービスの計測用に作られた解析サービス(Firebase AnalyticsやFacebook Analyticsなど)は、ここらの計測を自動でやってくれますが、Google Analyticsは自前でしっかり実装しなければなりません。

知れること

購入されたアイテムの個数や合計金額など課金に関するイベントが計測できるようになります。

Google Analyticsの計測で全てを賄おうとしていて、課金機能が搭載されているサービスでは必須な計測要件だと思います。

計測方法

課金のサンプルを用意するのが大変だったので、実際にプロダクトに導入したものを紹介したいと思います。

import StoreKit
// 課金処理が成功した後に呼ばれる
func purchased(product: SKProduct, transaction: SKPaymentTransaction, queue: SKPaymentQueue) {
    // レシート検証、忘れずに!!

    let tracker: GAITracker = self.tracker()
    let currency: String = product.priceLocale.currencyCode ?? ""
    var builder = GAIDictionaryBuilder.createTransaction(withId: transaction.transactionIdentifier ?? "",
                                                         affiliation: "In-app Store",
                                                         revenue: product.price, // 課金された金額
                                                         tax: 0, // 消費税
                                                         shipping: 0, // 送料
                                                         currencyCode: currency)
    let params1 = builder?.build() as [AnyHashable: Any] {
    tracker.set(kGAICurrencyCode, value: currency)
    tracker.send(params1)

    builder = GAIDictionaryBuilder.createItem(withTransactionId: transaction.transactionIdentifier ?? "",
                                              name: product.localizedTitle, // 商品名
                                              sku: "", // Stock Keeping Unit
                                              category: "", // 商品のカテゴリ
                                              price: product.price, // 金額
                                              quantity: 1, // 個数
                                              currencyCode: currency)
    let params2 = builder?.build() as! [AnyHashable: Any]
    tracker.set(kGAICurrencyCode, value: currency)
    tracker.send(params2)
}

これを送信すれば課金イベントとして、Eコマースの部分で表示されるようになります。

これとは別にアプリ計測用に拡張Eコマースというものがあるのですが、こちらは課金するまでの行動と離脱などを計測できるものがありますが、まだしっかりとした数字が取れていないので確認出来次第別途書き足したいと思います。

最後にユーザーにサービス特有の属性を付与できるカスタムディメンションの紹介をします。

カスタムディメンション

サービス特有の値でセグメントをきりたい時に役立つものになります。

知れること

ユーザーの属性をカスタムで付与することで様々なセグメントを切れるようになります。

例えば(ありきたりですが…)

  • 「お気に入り」をたくさんしているユーザーはリテンションが高いのか?
  • 連続○日アプリを起動してくれるユーザーは課金率が高いのか?

などといったサービス特有の属性に合わせたセグメントからスクリーンやイベント、課金情報などを絞り込むことが出来ます。

無料枠だと25個しか設定出来ない & 一度作ったら消せないという問題があるので無駄に利用は出来ませんが、試してみる価値は大いにあると思います。

計測方法

カスタムディメンションを使用する前にGoogleAnalyticsの管理画面側でやらなければならないことがあるので、まずはそちらから紹介します。

管理画面で設定

設定 > アカウント > プロパティの中のカスタムディメンションを選択して下さい。

ScreenShot6

ここで新しいカスタムディメンションを作ります。

ScreenShot7

サンプルで、「ボタンをタップした回数」というディメンションを作りました。

これで作成ボタンを押すと以下のソースコードが書いてあるページに遷移します。

iOSに限定

NSString *dimensionValue = @"SOME_DIMENSION_VALUE";
[tracker set:[GAIFields customDimensionForIndex:1] value:dimensionValue];

ここのGAIFields customDimensionForIndex:1の部分がカスタムディメンションで付与するindex番号になります。

ここがずれると値が間違ってしまうので気をつけてください。

では実際にイベントやスクリーンに反映される実装を紹介します。

計測方法

カスタムディメンションはGAITrackerにセットするのでイベントやスクリーンを送る前にセットしている必要があります。

そのためアプリ内で使うGAITrackerは共通でカスタムディメンションが設定されるように実装してください。

またセットする値は上書きされてしまうので、継続して値を送りたい場合はUserDefaulstsなどで永続化する処理を入れるようにしてください。

extension ViewController {

    func tracker() -> GAITracker? {
        let tracker = GAI.sharedInstance().defaultTracker
        tracker?.allowIDFACollection = true
        // ボタン押した数を継続的にとりたいのでUserDefaultsで永続化
        let tapCount = UserDefaults.standard.integer(forKey: "customDimensionTapCount")
        // 先ほど作ったindex = 1のfieldを生成
        let field = GAIFields.customDimension(for: 1)
        // fieldとvalue(String)をセット
        tracker?.set(field, value: "\(tapCount)")
        return tracker
    }

}

GAITrackerにカスタムディメンションをセットした状態でスクリーンやイベントを送信すると以下のようなログが流れます。

VERBOSE: GoogleAnalytics 3.17 -[GAIBatchingDispatcher persist:] (GAIBatchingDispatcher.m:518): Saved hit: {
    parameters =     {
        "&aid" = "com.example.SampleGoogleAnalytics";
        "&an" = SampleGoogleAnalytics;
        "&ate" = 1;
        "&av" = "1.0.0";
        "&cd1" = 6;
        "&ds" = app;
        "&ea" = "\U30bf\U30c3\U30d7";
        "&ec" = TOP;
        "&el" = "\U30dc\U30bf\U30f3";
        "&t" = event;
        gaiVersion = "3.17";
    };
    timestamp = "2017-10-12 14:07:04 +0000";
}

上記の"$cd1"CustomDimension(index番号)となって右辺にセットした値がつくようになると思います。

上記のログはボタンを6回タップしているという情報をイベント一緒に送っています。

カスタムディメンションの値の反映タイミングは不確かなので確認に手間取るかと思いますが、ログで送られていれば確実に送信出来ているので大丈夫です。

終わりに

今回書いたソースコードは以下のレポジトリにおいておきました。

今回は長く使われているであろうGoogle Analyticsの使い方の紹介をさせていただきました。

GoogleAnalytics以外にも弊社漫画PF事業部のクライアントエンジニアは勝手に色々な計測ツール使ってピンポイントで計測を行ってチームメンバーにに進言したりするので、そういうツール達も紹介できればなと思っています。

サービスの計測が大好きな人や計測周りで困っているエンジニアさんがいらっしゃいましたら、お話ししたいのでぜひ連絡ください!