Carthageの導入で困った7つのこと
先日仕事で初めてCarthageを利用した際に困った点やつまづいた点。
ラインナップ
- Carthage関連ファイルどこまでcommitするか問題
- carthageのコマンド多くてどれ使えば良いかよく分からない問題
- Fabric/Crashlyticsが公式にサポートしてない問題
- Firebaseが公式にサポートしてない問題
- Firebase.frameworkがbitcodeサポートしてない問題
- App Installation Failed 問題
- binaryダウンロードのバージョン解決に不具合がありそう?問題
Carthage関連ファイルどこまでcommitするか問題
CartfileとCartfile.resolvedは必須として以下のファイル群をcommitするのかどうかという話。
- Carthage/Checkouts
- Carthage/Build
世間には色々な意見があるようだけど、私個人としては以下を理由として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はサポートされてないので代替手段を検討する必要があります。
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: メンテされてるレポジトリはここ
Firebaseが公式にサポートしてない問題
Firebaseも同じく公式にはまだサポートされてないのですが、こちらはバイナリダウンロード用のjsonファイルを公式が試験的にメンテしてくれているようです。フィードバック次第では今後Carthageを公式にサポートする可能性もあるようです。
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しようとするとエラーが...
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の対象にできないようです。以下参照。
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をよく見ろと言う話でした。
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がダウンロードされていたのは正常な動作でした。