『入る学科間違えた高専生』の日記

プログラミングのコードを書いたりする予定です。あとは日記等。あといつまで高専生やねん

Swift Package Manager で Firebase をインストールしたときの Crashlytics の設定

はじめに

iOS アプリ開発 ( Android アプリもね) には欠かせない FirebaseCrashlytics (以下, Crashlytics) .
Swift Package Manager (以下, SwiftPM ) で Crashlytics をプロジェクトにインストールしているときに手動で dSYM をアップロードすることのメモ的備忘録です.

ダラダラと書くので結論だけ欲しい人は,目次の 解決法 からどうぞ

想定の構成は以下のような感じです. f:id:nanashinodonbee:20210823072357p:plain

導入

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 では gymscan には -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",
    )

という感じでしょうか.
fastlanexcodebuild というアクションは用意されていますが,複雑なので gymscan を使いましょう *3 というようなことも書かれていました.
実際のコードを見てみた感じ -resolvePackageDependencies だけをさせたい場合のことは考慮されていない*4ようでした.
単純に僕の Ruby と xcodebuild 力が低すぎてわかってないだけかもしれない.

最後に

今回は, Crashlytics を SwiftPM でインストールしている場合に dSYM のアップロードを手動で行う際の方法を書きました.
また,参考にも書いていますが,今回の -clonedSourcePackagesDirPath を使って SwiftPM のクローンパスを指定してあげることで Bitrise や GitHub Actions , CircleCI , Jenkins おじさんなどの CI/CD でもいい感じにキャッシュが出来て時間短縮の効果にもなるかと思います.

また,最後に示した fastlane の download_dsymsupload_symbols_to_crashlytics の流れの部分で upload-symbols を取得するために回りくどいことをやってたりいろんな依存ライブラリをフェッチしてきているので無駄が多いので公式も書いている通り GitHub から upload-symbolsrun をダウンロードしてきて実行権限付与して実行してあげるのも手かと思います.

今回は紹介を端折りますが Package.swift でライブラリ管理するのも大いにありだと思います.
Xcode での SwiftPM でのライブラリ管理はプロジェクトを開くたびに依存解決が実行されてしまったりビルドするまでに時間がかかってしまったりなどちょっとデメリットもあるのでまだなかなか移行しにいく状況が続いています.(いろいろ理由があるのだ)

参考

firebase.google.com

qiita.com