31
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

スピカ(ネイルブック💅)Advent Calendar 2015

Day 2

iOSアプリでカジュアルにGoogleAnalyticsを埋め込んでる話

Last updated at Posted at 2015-12-01

スピカ Advent Calendar 2015 | Qiitaの2日目の投稿です。

iOSアプリでカジュアルにGoogleAnalyticsを埋め込んでる話

Google-Analytics.jpg

はじめに

みなさんはiOSアプリを開発されている際にGA(GoogleAnalytics)は使われていますか?
GAとはみなさんご存知の通りGoogleが出してる無料で使える高機能なアクセス解析ツールですね、当社スピカが出しているネイルブック・サロンブックでももちろん利用しておりますが、この記事では当社のiOSアプリであるサロンブックがどのようにしてカジュアルにGAをアプリに埋め込んで運用しているのかを説明していきます。

サロンブックでのGoogleAnalyticsの運用方法

スクリーンショット 2015-12-01 21.11.57.png

GoogleSpreadSheetでGAの定義を管理

GAの定義をGoogleSpreadSheetで管理していて、以下のような定義書になっております

スクリーンショット 2015-12-01 21.26.54.png

まず主要な定義の説明をしていきます

  • 利用中

    • 1:利用中0:未利用という風に管理しており利用中である場合のみ動的にコードからGAを埋め込むための定義を生成するようになってます
  • カテゴリ

    • GAで解析する際のカテゴリ欄の説明です
  • 項目

    • GAで解析する際の項目欄の説明です
  • GAカテゴリ

    • 動的にコードからGAの定義を生成する際に利用する、カテゴリの識別子です
  • GAアクション

    • 動的にコードからGAの定義を生成する際に利用する、アクションの識別子です
  • GAラベル

    • 動的にコードからGAの定義を生成する際に利用する、ラベルの識別子です
  • GA値

    • 動的にコードからGAの定義を生成する際に利用する、バリューの識別子です
  • iOS:Class

    • 動的にコードからGAの定義を生成する際に利用する、iOSアプリのGAの埋め込みを動的に行う対象のクラス名です
  • iOS:MethodSignature

    • 動的にコードからGAの定義を生成する際に利用する、iOSアプリのGAの埋め込みを動的に行う対象のメソッドシグニチャ名です

このようにただのドキュメントの定義書だけではなく、実際に動くコードの自動化を助けるためのリソースの側面としても合わせて運用を行なっております、これをどのようにコードに持っていくかを次に説明していきます。

GoogleSpreadSheetをplistに変換

もちろんこのままじゃGoogleSpreadSheetからGAの定義を取得することは難しいのでtsvファイルとしてダウンロードしてきます。そしてそのtsvファイルに対してRubyのスクリプトを実行することでplistの形式に変換していきます。
plistの形式に変換する際のフォーマットはこちらを参照、見てわかるようにGoogleAnalyticsをアスペクト指向的に埋め込むことを助けてくれるライブラリであるGADIを利用しております。

plistから実際にiOSアプリにGAを埋め込む

GADInjector.injectWithTrackingID(GLOBAL.GA_TRACKING_ID,
    configPropertyListPath:NSBundle.mainBundle().pathForResource("GoogleAnalyticsConfig.plist", ofType:nil)) {
        (config: [NSObject : AnyObject]!, field: GADField!) -> Bool in
        let status = userRepository.loginUserStatus
        field.addCustomDimension(GACustomDimension.loginUserStatus(status))
                
        field.addCustomDimension(GACustomDimension.installSource(attributes.installSource.value!))
        
        return true
}
        
GADInjector.injectWithTrackingID(GLOBAL.GA_TRACKING_ID,
    configPropertyListPath:NSBundle.mainBundle().pathForResource("GAEventTrackingConfig.plist", ofType:nil)) {
        (config: [NSObject : AnyObject]!, field: GADField!) -> Bool in
        let status = userRepository.loginUserStatus
        field.addCustomDimension(GACustomDimension.loginUserStatus(status))
        
        field.addCustomDimension(GACustomDimension.installSource(attributes.installSource.value!))
        
        return true
}

実際のコード例でいくと上のようになります、GADIはカスタムディメンションの埋め込みにも対応できるようになってるのでサロンブックアプリではGAの定義を流しこみつつ、どこからの流入か、ログインの状態を把握するための対応をこれだけの行数で済ませることができています。
アスペクト指向の応用が上手くハマってるパターンではないかと考えており、このようなトラッキングのような要件に対して柔軟に使っていけるのではないでしょうか。
ちなみに当初はカスタムディメンションは入れておらず運用してましたが、ログイン率が見たいという要件に対して1週間かからない工数で対応することができたので大幅な作業の短縮に貢献してくれました。

さいごに

普通だったらチマチマコードに埋め込まないといけないGAですが、当社ではこのようにカジュアルにGAを扱えるようにしたことによって短縮できた時間を使って他の問題を取り組むことを可能にしています。
是非興味がありましたらこのようなシステム作りをして幸せなアプリ開発を実現していきましょう!

関連リンク

31
30
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
31
30

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?