アカベコマイリ

HEAR NOTHING SEE NOTHING SAY NOTHING

Xcode 11 (Swift) で Google Analytics 環境を構築する

Xcode 11 (Swift) で開発している iOS アプリのプロジェクトから Google Analytics を利用しようとして苦戦したので、その覚書。

はじめに以下の公式リファレンスを読みながら環境構築を試みた。

API は CocoaPods により提供されている。当該プロジェクトは FMDB もこれで管理していたので、以下のように Pods ファイルを書いて pod install した。

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'SampleApp' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  # Pods for SampleApp
  pod 'FMDB/FTS'
  pod 'GoogleAnalytics'

  target 'SampleAppTests' do
    inherit! :search_paths
    # Pods for testing
  end
end

SampleApp.xcworkspace を Xcode で開くと Pods 側へ GoogleAnalytics という名で関連する設定が追加されていた。FMDB は CocoaPods から追加された時点で自動的に Swift からの参照も解決してくれるようで、そのまま import FMDB 可能。しかし Google Analytics は資料によると手動で参照追加しなければならない。

ここからが苦戦した点。資料には以下のように説明されている。

これらの変更を行うには、まず Swift プロジェクトに BridgingHeader が含まれていることを確認してから、 この BridgingHeader 内にアナリティクスを追加します。

Swift から Objective-C の実装を参照するためには BridgingHeader が必要で、それを追加しなければならない。Apple 公式の

には Objective-C ファイルの参照を追加しようとすれば、自動的に bridging header を生成するためのダイアログが表示されるとあった。この説明が曲者で、Objective-C ファイルなのだから以下のようにした。

  1. File - New... で新規ファイル追加ダイアログを開く
  2. Objective-C File を選択
  3. 適当な名前を付けて新規作成

間違ったファイル指定

しかし bridging header 生成ダイアログは表示されない。もしかして Xcode 11 だとこの方法が対応していないのか?と早合点して、次は bridging header を手動追加することにした。以下、参考記事。

Build Settings をいじり、ヘッダーも以下のように定義した。

//
//  SampleApp-Swift.h
//  SampleApp
//
//  Created by akabeko on 2020/02/12.
//  Copyright © 2020 Akabeko All rights reserved.
//

#ifndef Sample_h
#define Sample_h

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

#endif /* SampleApp-Swift_h */

しかし Google Analytics 資料にある GAI.sharedInstance() などの参照がエラーになる。もしかしてプロジェクト固有の設定が問題かも?と新規 Xcode プロジェクトを作成して設定してみるも、やはり上手くゆかず。

ここでもう一度、Apple 資料を振り返る。単に私が手順をミスっているだけで、正しく実行したなら bridging header 生成ダイアログが表示されるのでは、と。そして再び新規ファイル作成ダイアログを開き、気づいた。追加するのは Objective-C File ではなく Cocoa Touch Class なのではと。

正しいファイル指定

これを選ぶと確かに Apple の資料どおり bridging header 生成ダイアログが表示された。自分で命名した Cocoa Touch Class のヘッダー、実装ファイルと共に SampleApp-Bridging-Header.h が生成されている!そして Google Analytics 資料に従い以下を定義してみたところ、

//
//  Use this file to import your target's public headers that you would like to expose to Swift.
//

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

以下のような参照がエラーとならず、無事にビルドを通せた。

guard let gai = GAI.sharedInstance() else {
    assert(false, "Google Analytics not configured correctly")
}

プロジェクト設定も適切に指定されるようだ。Git の差分からもそれがうかがえる。

しかし解決したからよかったものの、FMDB のように CocoaPods として参照解決する設計になっていて欲しかった。CocoaPods 向けライブラリーを作ったことないので、これが当たり前なのか、FMDB の配慮が素晴らしいのかはわからないけれど。

Xcode についても改善してほしい。Objective-C と Swift を仲介する重要な機能なのだから、アプリケーションのメニューに同等の機能がほしい。今回の操作も好意に解釈するなら「必要に応じて自然に提供」とも言える。しかしヘッダーとプロジェクト設定が欲しいだけなら無駄なファイルが作られるし、Apple 資料を読んでいないと操作を想像するのは難しい。

まとめ

教訓。

  • 公式資料どおりにゆかない場合、まずは自分が手順を間違えていないか疑うべし
  • 手順で曖昧な点があれば、類似するものを試すべし
  • 万策尽きて、はじめてググるべし

長くプログラマーやってても、こういう小さな (そして時間的には大きな) つまづきに遭遇することはある。経験と Web 上の知見により大抵は問題化する前に解決するのだが、たまにこういうことがあると自身の慢心・過信をよい感じに諌めてくれて、新鮮な気分に戻れる。プログラマーの醍醐味でもある。