[iOS] Flutter engineのクラッシュをCrashlyticsで解析する
これは何?
Flutter製iOSアプリでCrashlyticsに頭を悩まされ夜も眠れない人向けの記事です。
Flutter engineのコードでクラッシュが起きている場合の解析は一工夫いりますという話です。
TL;DR
Read this.
あらすじ
自分はもう長いこと業務でFlutterでiOS向けにアプリを展開していますが、ずっと前からある問題に悩まされていました。
Flutter内部でクラッシュが起きたとき、Crashlyticsで詳細がわからない
要するにこんな感じです。

シンボルが不足しています
これでは解析もクソもありません。原因が何もわからん。
この現象は、通常ドキュメントにも書いてある dSYM ファイルをアップロードすることで回避できます。
しかし、この操作を行ってもなお詳細がわからないことがあります。
上の画像をよく見てみると、トレースの番号の隣に Flutter と書いてあるので、これは Flutter.framework の内部のトレースであることがわかります。
そして、Flutter.framework のdSYMファイルはアプリのビルド時には生成されません。

OMG
通りでdSYMを全部アップロードしたつもりでも シンボルが不足しています などと言われるわけですね。
実際、ビルド後のアーカイブ ( build/ios/archive/Runner.xcarchive/dSYMs/ ) を見てみると Flutter.framework.dSYM は見当たりません。
ではどうすれば?
issueを探していたら答えは見つかりました。
Starting with flutter/engine@931d3cb the buildbots are uploading a dsym file for Flutter.framework in release mode. The files can be obtained from our cloud storage bucket by constructing an URL as follows:
https://storage.cloud.google.com/flutter_infra/flutter/<ENGINE_REVISION>/ios-release/Flutter.dSYM.zip
Flutterチーム側で、releaseビルドのときのdSYMファイルを個別にCloud Storageに置く対応を行ってくれていました!
(開発者側でdSYMファイルを作成する方法もありますが、実際にはできなかったようです)
そして現在Flutter本体リポジトリのwikiにはちゃんと記載があります。
The dSYM file for Flutter.framework (which is the Flutter Engine) for ios-release builds can be downloaded from Google Cloud Storage. Follow the steps from the Android section in this guide, but in the last step use a download url following this schema:
https://storage.cloud.google.com/flutter_infra_release/flutter/38a646e14cc25f5a56a989c6a5787bf74e0ea386/ios-release/Flutter.dSYM.zip(replace the engine hash with your hash).
というわけで、アプリ開発者がFlutter engine起因のクラッシュレポートを解析するためには
- 利用しているFlutterのバージョンに対応するengineのバージョン(コミットハッシュ)を取得する
-
https://storage.cloud.google.com/flutter_infra_release/flutter/<ENGINE_REVISION>/ios-release/Flutter.dSYM.zipの<ENGINE_REVISION>に取得したengineのバージョンを入れてアクセスする - zipファイルがダウンロードできるので、それをそのままCrashlyticsのコンソールからアップロードする
以上になります。
engineのバージョンを調べる方法
Flutter engineのバージョンを調べる必要が出てきましたが、そんなのどうやって調べれば?と思う人も少なくないと思います。普通にアプリ開発をしていてもまず意識しないです。
ただし、これは簡単に調べることができます。以下の手順を踏んでみましょう。
- GitHubで flutter/flutter にアクセスする
- 利用しているFlutterのバージョンに合わせたリビジョンに移動する

タグで検索すると楽 -
bin/internal/engine.versionファイルを開く - engineのバージョンを示すコミットハッシュが書いてある
こんな感じです。
おわりに
これでFlutter engine側でクラッシュが起きたときでも安心して調査できます。
やったね。
やること自体は単純なので、例えばFlutterのアップデートを自動化してるリポジトリだったらCIの中に組み込んでもよし、あるいは手動で動かすワークフローとして個別にスクリプトを書いておくのもいいかもしれません。
いつかGitHub Actionsとして作るかも。
Discussion
こちらは、以下でしょうか?
flutter_infra_releaseの部分が異なるようでした。ご指摘ありがとうございます!元のissueコメントの方にあったURLを引っ張ってきてしまってました。
修正済みです🙇