はじめに
iOS アプリ開発 ( Android アプリもね) には欠かせない FirebaseCrashlytics (以下, Crashlytics) .
Swift Package Manager (以下, SwiftPM ) で Crashlytics をプロジェクトにインストールしているときに手動で dSYM をアップロードすることのメモ的備忘録です.
ダラダラと書くので結論だけ欲しい人は,目次の 解決法 からどうぞ
想定の構成は以下のような感じです.
導入
Xcode 上の Build Phases の Run Script で対応する場合
CocoaPods でインストールする場合は,
"${PODS_ROOT}/FirebaseCrashlytics/run" "-gsp" "${SRCROOT}/path/to/GoogleService-Info.plist"
とサクッと対応することは可能ですね.
表題で指定した SwiftPM では
"${BUILD_DIR%Build/*}/SourcePackages/checkouts/firebase-ios-sdk/Crashlytics/run" "-gsp" "${SRCROOT}/path/to/GoogleService-Info.plist"
このパスについては GitHub の Issue のコメント *1 で書かれていますね.
また,ドキュメントの方にも書かれています.*2
また,どちらとも Input Files
に以下が追加必要です.
${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${TARGET_NAME} $(SRCROOT)/$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)
さて,バイナリの Bitcode を有効にしているアプリ ( App Store Connect に送信済み) や CI 上などでビルドしたアプリの dSYM を手動で Crashlytics に送信することを考えましょう.
CocoaPods でインストールした Crashlytics に関しては, Pods
を Git 等で管理していない環境下でも upload-symbols
コマンドのある場所が簡単に特定できますね.
$ pod install $ ./Pods/FirebaseCrashlytics/upload-symbols -gsp /path/to/GoogleService-Info.plist -p ios /path/to/dSYMs
SwiftPM での ${BUILD_DIR%Build/*}
ってなんでしょうね.全く見覚えのない子ですね?
こいつを今回は解決したいと思います.
前提
SwiftPM が簡単に扱えるようになった Xcode 11 以上なら今回の方法は扱えると思います. Xcode 11 使ってる人はいないと思いますけどね
解決法
ダラダラと書いてしまったのでまずは解決法を書いておきます.
xcodebuild
に -clonedSourcePackagesDirPath
というパラメータが増えているのでこいつに自分が設置したいパスを設定するだけということです.
$ xcodebuild -resolvePackageDependencies -clonedSourcePackagesDirPath ./.swiftpm $ ./.swiftpm/checkouts/firebase-ios-sdk/Crashlytics/upload-symbols -gsp /path/to/GoogleService-Info.plist -p ios /path/to/dSYMs
という感じですね.
今回は, .swiftpm
というディレクトリを指定しました.
App Store Connect から dSYM を拾ってくる場合は多くの方が fastlane
を扱っていると思うのでこちらも一応
fastlane では gym
や scan
には -clonedSourcePackagesDirPath
に当たるものとして cloned_source_packages_path
がパラメータとして準備されています.
参考までに gym では
gym( scheme: "App", project: "App.xcodeproj", export_method: "app-store", configuration: "Release", cloned_source_packages_path: "./.swiftpm", )
よくある, App Store Connect から dSYM をダウンロードしてきて Crashlytics にアップロード
sh("xcodebuild -resolvePackageDependencies -clonedSourcePackagesDirPath ./.swiftpm") download_dsyms( username: "#{email}", team_id: "#{team_id}", app_identifier: "#{app_identifier}", version: "latest", ) upload_symbols_to_crashlytics( gsp_path: "/path/to/GoogleService-Info.plist", platform: "ios", binary_path: "./.swiftpm/checkouts/firebase-ios-sdk/Crashlytics/upload-symbols", )
という感じでしょうか.
fastlane
に xcodebuild
というアクションは用意されていますが,複雑なので gym
や scan
を使いましょう *3 というようなことも書かれていました.
実際のコードを見てみた感じ -resolvePackageDependencies
だけをさせたい場合のことは考慮されていない*4ようでした.
単純に僕の Ruby と xcodebuild 力が低すぎてわかってないだけかもしれない.
最後に
今回は, Crashlytics を SwiftPM でインストールしている場合に dSYM のアップロードを手動で行う際の方法を書きました.
また,参考にも書いていますが,今回の -clonedSourcePackagesDirPath
を使って SwiftPM のクローンパスを指定してあげることで Bitrise や GitHub Actions , CircleCI , Jenkins おじさんなどの CI/CD でもいい感じにキャッシュが出来て時間短縮の効果にもなるかと思います.
また,最後に示した fastlane の download_dsyms
→ upload_symbols_to_crashlytics
の流れの部分で upload-symbols
を取得するために回りくどいことをやってたりいろんな依存ライブラリをフェッチしてきているので無駄が多いので公式も書いている通り GitHub から upload-symbols
と run
をダウンロードしてきて実行権限付与して実行してあげるのも手かと思います.
今回は紹介を端折りますが Package.swift
でライブラリ管理するのも大いにありだと思います.
Xcode での SwiftPM でのライブラリ管理はプロジェクトを開くたびに依存解決が実行されてしまったりビルドするまでに時間がかかってしまったりなどちょっとデメリットもあるのでまだなかなか移行しにいく状況が続いています.(いろいろ理由があるのだ)
参考
*1:https://github.com/firebase/firebase-ios-sdk/issues/6464#issuecomment-698456415
*2:https://github.com/firebase/firebase-ios-sdk/blob/master/SwiftPackageManager.md
*3:https://docs.fastlane.tools/actions/xcodebuild/
*4:https://github.com/fastlane/fastlane/blob/114e5ecd8826262a8d1df913e1d1ddffe776c962/fastlane/lib/fastlane/actions/xcodebuild.rb