tofucodes diary

にほんごのほう

Carthageの導入で困った7つのこと

先日仕事で初めてCarthageを利用した際に困った点やつまづいた点。

ラインナップ

  1. Carthage関連ファイルどこまでcommitするか問題
  2. carthageのコマンド多くてどれ使えば良いかよく分からない問題
  3. Fabric/Crashlyticsが公式にサポートしてない問題
  4. Firebaseが公式にサポートしてない問題
  5. Firebase.frameworkがbitcodeサポートしてない問題
  6. App Installation Failed 問題
  7. binaryダウンロードのバージョン解決に不具合がありそう?問題

Carthage関連ファイルどこまでcommitするか問題

CartfileとCartfile.resolvedは必須として以下のファイル群をcommitするのかどうかという話。

  • Carthage/Checkouts
  • Carthage/Build

qiita.com

世間には色々な意見があるようだけど、私個人としては以下を理由としてCheckouts, Build共にcommitしない方針にしました。

  • Cartfile.resolvedがあれば原則的には同じ開発環境を作れる
  • Githubに不要なDiffが出るのが好きじゃない
  • 現状はCIをしていないのでビルド時間にそこまでシビアになる必要がない

仕事ではチームで開発を行ってるため上記のような方針にしましたが、個人開発とかでGithubのPull Request運用じゃない環境だったら2番目の理由は当てはまらなくなるんで、好きなファイルcommitしてしまえば良いんじゃないんですかね。

carthageのコマンド多くてどれ使えば良いかよく分からない問題

$ carthage
Available commands:

   archive           Archives built frameworks into a zip that Carthage can use
   bootstrap         Check out and build the project's dependencies
   build             Build the project's dependencies
   checkout          Check out the project's dependencies
   copy-frameworks   In a Run Script build phase, copies each framework specified by a SCRIPT_INPUT_FILE environment variable into the built app bundle
   fetch             Clones or fetches a Git repository ahead of time
   help              Display general or command-specific help
   outdated          Check for compatible updates to the project's dependencies
   update            Update and rebuild the project's dependencies
   version           Display the current version of Carthage
  • archive = frameworkを提供するときに必要そうな感じ
  • bootstrap = build + checkoutな感じだけどそれぞれがよく分からない
  • build = frameworkをビルドするコマンド?
  • checkout = ?
  • fetch = ??
  • update = ライブラリのバージョンアップしたい時に必要そうな感じ

自分の最初の印象としてはこんな感じでした。 しかもそれぞれのコマンドにさらにたくさんのオプションまで用意されててもう何が何だか....

結論、簡単に使うなら以下くらいで大丈夫な気がしてます。

# Carthage導入時
$ carthage update --platoform iOS

# Carthage導入済みのプロジェクトをcloneしてきて依存ライブラリをビルドする最初のステップ
# Cartfile.resolvedの内容を元にビルドされます
$ carthage bootstrap --platform iOS

# (全ての)依存ライブラリをバージョンアップする時
$ carthage update --platform iOS --cache-builds

# 特定の依存ライブラリをバージョンアップする時
$ carthage update "$LIBRARY_NAME" --platform iOS

FYI: 各コマンドのオプションの詳細は以下のコマンドで見れる

# carthage help <command name>
$ carthage help bootstrap

Fabric/Crashlyticsが公式にサポートしてない問題

FabricとCrashlyticsはCocoaPodsはサポートしてるけどCarthageはサポートされてないので代替手段を検討する必要があります。

github.com

Carthageのバイナリ形式ダウンロードで必要になるjsonファイルを親切な人がメンテしてくれてるので、私はこちらをありがたく利用させてもらいました。

binary "https://raw.githubusercontent.com/Building42/Specs/master/Carthage/Fabric.json"
binary "https://raw.githubusercontent.com/Building42/Specs/master/Carthage/Crashlytics.json"

FYI: メンテされてるレポジトリはここ

github.com

Firebaseが公式にサポートしてない問題

Firebaseも同じく公式にはまだサポートされてないのですが、こちらはバイナリダウンロード用のjsonファイルを公式が試験的にメンテしてくれているようです。フィードバック次第では今後Carthageを公式にサポートする可能性もあるようです。

github.com

binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseAnalyticsBinary.json"
binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseAuthBinary.json"
binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseDatabaseBinary.json"
binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseDynamicLinksBinary.json"
binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseMessagingBinary.json"

Firebase.frameworkがbitcodeサポートしてない問題

前述のようなCartfileでダウンロードを行うとFirebase.frameworkというframeworkがダウンロードされるので何も考えずにアプリにリンクしたところbitcodeがサポートされてないというエラーになりました。

$ otool -l Carthage/Build/iOS/Firebase.framework/Firebase | grep __LLVM
# 何も出力されない

対応の結論としては、Firebase.framework自体の中身と、CocoaPods時代にこのframeworkをリンクしていなかったことから判断して、Firebase.frameworkはアプリにリンクしませんでした。

App Installation Failed 問題

全ての依存ライブラリをCarthageに移行していざアプリをRunしようとするとエラーが...

f:id:tofucodes:20180421175259p:plain

This application or a bundle it contains has the same bundle identifier as this application or another bundle that it contains. Bundle identifiers must be unique.

原因はFirebaseのframeworkをCarthageのcopy-frameworksの対象にしてたことでした。Firebaseのframeworkはstatic libraryになっており、static libraryはcopy-frameworksの対象にできないようです。以下参照。

github.com

binaryダウンロードのバージョン解決に不具合がありそう?問題

Carthageに移行前CocoaPodsで4.9.0のFirebase SDKを利用していたので、Carthageでも以下のようなバージョン指定でダウンロードを試みました。私の認識が正しければ、以下のようなバージョン指定では4.9.Xの最新版をダウンロードしてくれるものかと思ってました。

binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseAnalyticsBinary.json" ~> 4.9.0

しかし実際のところcarthage updateを実行するとダウンロードされたバイナリは4.12.0(4.Xの最新版)でした。これがCarthageのバグなのか私の認識違いなのかまだ不明なので分かる方がいたら教えてほしいです。

もし4.9.0をダウンロードしたい場合は以下のように厳密に指定してあげれば可能です。

binary "https://dl.google.com/dl/firebase/ios/carthage/FirebaseAnalyticsBinary.json" == 4.9.0

上記の挙動については私の認識違いでした。 CarthageのREADMEをよく見ろと言う話でした。

github.com

Compatibility is determined according to Semantic Versioning. This means that any version greater than or equal to 1.5.1, but less than 2.0, will be considered “compatible” with 1.5.1.

互換性の定義は Semantic Versioning の定義に従い、~> 1.5.1 は 1.5.1以上2.0未満となる。

According to SemVer, any 0.x.y release may completely break the exported API, so it's not safe to consider them compatible with one another. Only patch versions are compatible under 0.x, meaning 0.1.1 is compatible with 0.1.2, but not 0.2. This isn't according to the SemVer spec but keeps ~> useful for 0.x.y versions.

Semantic Versioning によると、0.x.y の場合はすべて互換性が無いものと考える。(しかしCarthageは?)パッチバージョンアップを互換性ありと考えるようにする(0.1.1 -> 0.1.2は互換性あり、0.1.2 -> 0.2 は互換性なし)。これはSemantic Versioningに則ってないけど、0.x.yのバージョンの場合は便利

つまりFirebaseのライブラリを~> 4.9.0と指定しているにも関わらず4.12.0がダウンロードされていたのは正常な動作でした。