LoginSignup
3
3

More than 5 years have passed since last update.

Firebaseの新しいSDKを使いたい場合は、Cocoapodsの1.0.0以上を利用する

Last updated at Posted at 2016-05-23

TL;DR

先日公開されたFirebaseの新しいSDKを使いたい場合は、Cocoapodsの1.0.0以上を利用してSDKの導入を行う。
ロギング時のAOPライブラリでAspectsを利用している場合に、エラーが出る場合はMOAspectに乗り換えよう。

悩んだこと

Cocoapodsのバージョン0.39.0で新しくなったFirebaseのSDKをインストールしようとすると、Segmentation fault: 11というエラーが発生してビルドができない。FIRで始まるクラスがコード上に出現しなければ(コメントアウトなどをして)ビルドが成功するので、FirebaseのSDKのインストール方法に問題がありそうな感じだった。

  1. While loading members for 'FIRDatabaseReference' at <invalid loc>
  2. While deserializing decl #101 (PATTERN_BINDING_DECL)
  3. While deserializing decl #2 (VAR_DECL)

解決策

StackOverflowに問題とその解決策があり、Cocoapodsのバージョンが古いことが問題のようだった。
http://stackoverflow.com/questions/37347327/upgraded-firebase-now-getting-swift-compile-error

アップデートしたら無事にコンパイルが成功した。
そんな一日。

おまけ

Cocoapodsの1.0.0を利用すると、スクリーン表示をGoogleAnalyticsに送信する際に利用しているAspects(https://github.com/steipete/Aspects)のインポート時に、エラーが出るようになってしまった。

スクリーンショット 2016-05-23 16.12.03.png

作っているアプリではGAへの送信のためだけにAOPを利用しているので、最悪各ViewControllerのviewWillAppear(_:)においてGAへの送信処理を書けば良いのだが気持よく無いので、代替ライブラリがないか、あるいはAspectsをCocoapodsを1.0.0で利用できるように出来ないか調査することにした。

iOSでAOPを行えるライブラリ

簡単に探した所、上記2つ。

結論

MOAspectsを利用したらすんなりいけた。
UIViewControllerのviewWillAppear(_:)のAfterにHookを設定し、ScreenTrackableというプロトコルに準拠したViewControllerの場合のみ、そのScreenTrackableプロトコルのtrackingというメソッドを実行するようになっている。

func setupHook() {
    MOAspects.hookInstanceMethodForClass(UIViewController.self,
        selector: #selector(UIViewController.viewWillAppear(_:)),
        position: .After,
        range: MOAspectsHookRangeAll) { (instance: AnyObject!) -> Void in
            if let instance = instance as? UIViewController {
                if let viewController = instance as? ScreenTrackable {
                    viewController.tracking()
                }
            }
    }
}

ちなみにScreenTrackableプロトコルはこんな感じ。

UIViewController+ScreenTrackable.swift
protocol ScreenTrackable {
    func tracking()
}

extension ScreenTrackable where Self: UIViewController {
    func tracking() {
        let sceneName = self.sceneName() // クラス名からGAに送信するファイル名を取得する(※1)
        Event.Screen(sceneName).send() // GAに送信
    }
}

クラス名からGAに送信するファイル名を取得する部分(※1)は、http://qiita.com/tattn/items/647e094936287a6bd2d3 などに方法が書かれている。更に、そのままクラス名を送信するのではなく、対応した日本語のスクリーン名に直して送信している。こうすることでGAで格段に見易くなる。

スクリーンショット 2016-05-23 16.24.22.png

3
3
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
3
3