.NET MAUI iOSアプリのFirebase Crashlytics「dSYMファイルが不足しています」警告の解消方法

.NET MAUI で作った iOS アプリを Firebase Crashlytics に接続すると、「This missing dSYM file is required to process crashes(クラッシュ解析に必要な dSYM ファイルが見つかりません)」という警告に悩まされがちです。この記事では、この警告がなぜ出るのか、そして .NET MAUI + iOS 特有のポイントを押さえながら、根本的な解決方法と運用ベストプラクティスを詳しく解説します。

目次

Firebase Crashlytics の「dSYM ファイルが不足しています」警告とは?

Firebase Crashlytics は、クラッシュしたときのスタックトレース(メモリアドレスの羅列)を、人間が読めるソースコードの行番号へ変換してくれるサービスです。

しかし、Crashlytics はその変換(シンボリケーション)を行うために「dSYM ファイル」という鍵を必要とします。dSYM がアップロードされていないと、次のような警告がダッシュボードに表示され、クラッシュログが解析されません。

This missing dSYM file is required to process crashes

.NET MAUI で作った iOS アプリでも、ネイティブ AOT コンパイルされたコードが iOS 上で動くため、ネイティブアプリと同様に dSYM が必須です。

dSYM とシンボリケーションの基礎知識

まずは用語を整理しておきましょう。

用語意味
Crashlyticsアプリのクラッシュレポートを収集・解析し、ダッシュボードで可視化してくれる Firebase のサービス。
dSYM ファイルビルド時に生成される「デバッグシンボル」のまとまり。メモリアドレスと関数名・ファイル名・行番号の対応表。
シンボリケーションクラッシュログに含まれるアドレス情報を、ソースコード上の場所(メソッド名や行番号)に復元する処理。

イメージとしては、

  • クラッシュログ … 暗号文
  • dSYM … 暗号を解く鍵

のような関係です。鍵(dSYM)が Firebase Crashlytics 側に届いていないと、Crashlytics は暗号文(クラッシュログ)を解読できず、「警告は出るのに中身が読めない」という状態になります。

.NET MAUI + iOS で dSYM 警告が出る典型パターン

.NET MAUI の iOS アプリの場合、次のような流れで dSYM がどこかで消えてしまうことが多いです。

フェーズやるべきこと.NET MAUI で起こりがちな問題
生成ビルド時に dSYM を出力するcsproj の DebugTypeportable などになっていて、完全な dSYM が生成されない
保持ビルド成果物から dSYM を消さないCI/CD でアーカイブやクリーン処理の過程で dSYM を削除してしまう
アップロードdSYM を Crashlytics に渡すupload-symbols スクリプトが未設定・権限不足・実行条件不備で実行されていない

つまり、

dSYM を「生成」 → 「保持」 → 「Crashlytics に渡す」

という 3 ステップのどこかで手が抜けていると、「dSYM ファイルが不足しています」警告に繋がります。以降の章では、この 3 ステップを順番に潰していきます。

.NET MAUI プロジェクトで dSYM を確実に生成する

最初のチェックポイントは、.NET MAUI プロジェクト(csproj)の設定です。Release ビルドでも完全なデバッグ情報が出るように、DebugTypefull に設定します。

csproj に DebugType=full を設定する

MAUI プロジェクトの .csproj に、次のような設定を追加します。

<PropertyGroup Condition="'$(Configuration)'=='Release'">
  <DebugType>full</DebugType>
</PropertyGroup>

既に DebugType が書かれている場合は、Release 構成だけ full になるように調整します。ターゲットフレームワークごとに分かれている場合は、iOS 向けのグループに書くとより安全です。

<PropertyGroup Condition="'$(Configuration)|$(TargetFramework)'=='Release|net8.0-ios'">
  <DebugType>full</DebugType>
</PropertyGroup>

代表的な DebugType の違いは次のとおりです。

特徴Crashlytics での利用
noneデバッグ情報を出力しないdSYM が生成されないため不可
portable.NET 共通のポータブル PDB を出力ネイティブ側の dSYM が不足しがちで、シンボリケーションに不十分
fullネイティブデバッグに必要な情報を含んだ完全版Crashlytics での解析に最も適している

.NET MAUI の iOS アプリは AOT コンパイルされたネイティブコードとして動作するため、ネイティブ側のシンボル情報がしっかり出ていることが重要です。

DebugSymbols や最適化との兼ね合い

Release ビルドでは最適化が有効になっており、デバッグビルドと比べてスタックトレースが多少変形します。それでも dSYM があれば Crashlytics 側がうまく復元してくれるので、

  • Release ビルドでも DebugType=full
  • 必要に応じて DebugSymbolstrue

とするのが安全です。

<PropertyGroup Condition="'$(Configuration)'=='Release'">
  <DebugType>full</DebugType>
  <DebugSymbols>true</DebugSymbols>
</PropertyGroup>

ここまで設定したら、一度クリーンして Release でビルドし、bin/Release 以下に dSYM が出力されているか確認します(Xcode のアーカイブ機能を使う場合は、アーカイブ内に .dSYM が含まれているかを後ほど確認します)。

Xcode 側で dSYM 出力設定と Bitcode を確認する

.NET MAUI で iOS アプリをビルドするとき、内部的には Xcode プロジェクトが生成されてビルドされています。Crashlytics の dSYM 警告を解消するには、Xcode 側の設定も確認しておきましょう。

Debug Information Format を「DWARF with dSYM File」に

Xcode で該当ターゲットを開き、

  • Build Settings > Debug Information Format

を確認します。値が DWARF with dSYM File になっていることが重要です。

設定値意味Crashlytics への影響
DWARF実行ファイルに最小限のデバッグ情報のみCrashlytics に渡す dSYM ファイルが生成されない場合がある
DWARF with dSYM FileDWARF に加えて dSYM ファイルを生成dSYM が生成され、Crashlytics でシンボリケーション可能

Debug/Release 両方の構成で確認しておきましょう。特に Release だけ DWARF になっているケースに注意です。

Bitcode を無効にする

古いプロジェクトでは Bitcode が有効になっている場合がありますが、現在は非推奨であり、dSYM 生成やシンボルアップロード周りでトラブルの原因になりがちです。

  • Build Settings > Build Options > Enable BitcodeNo に設定

特に Xcode のメジャーバージョンをまたいだときは、この設定が意図せず変わっていることがあるので注意してください。

Crashlytics への dSYM アップロードを自動化する

dSYM を生成できるようになったら、次はそれを Crashlytics に自動でアップロードする仕組みを整えます。最も一般的なのが、Firebase が配布している upload-symbols スクリプトを Xcode の Run Script Phase に追加する方法です。

CocoaPods で Firebase Crashlytics を導入している場合

CocoaPods を使っている場合、プロジェクト内に次のようなスクリプトが存在します。

  • ${SRCROOT}/Pods/FirebaseCrashlytics/upload-symbols

このスクリプトを、ビルド後に実行される Run Script として登録します。

  1. Xcode で iOS ターゲットを選択
  2. Build Phases タブを開く
  3. ボタンから New Run Script Phase を追加
  4. スクリプト欄に次を入力
"${SRCROOT}/Pods/FirebaseCrashlytics/upload-symbols" \
  -gsp "${PROJECT_DIR}/GoogleService-Info.plist" \
  -p ios "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}"

Release ビルドでのみ dSYM をアップロードしたい場合は、次のような条件付きで実行することもできます。

if [ "${CONFIGURATION}" = "Release" ]; then
  "${SRCROOT}/Pods/FirebaseCrashlytics/upload-symbols" \
    -gsp "${PROJECT_DIR}/GoogleService-Info.plist" \
    -p ios "${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}"
fi

このスクリプトが成功すると、ビルド完了時に dSYM が Crashlytics に送信されます。

実行権限エラーへの対処

スクリプト実行時に

Failed to upload dSYM

のようなエラーが出る場合、upload-symbols に実行権限が付いていないケースがあります。ターミナルで次のように実行権限を付与しておきましょう。

chmod +x "${SRCROOT}/Pods/FirebaseCrashlytics/upload-symbols"

CocoaPods を使わない MAUI iOS プロジェクトの場合

一部の .NET MAUI プロジェクトでは、CocoaPods を使わずに Firebase Crashlytics のバインディングライブラリを利用している場合があります。その場合は、Firebase CLI を使って dSYM をアップロードするのが分かりやすい方法です。

Firebase CLI で dSYM をアップロードする例

事前準備として、開発環境または CI 環境に Firebase CLI をインストールしておきます。その上で、次のようなコマンドで dSYM をアップロードします。

firebase crashlytics:symbols:upload \
  --app=<iOSアプリID> \
  <dSYMファイルまたはdSYMsディレクトリのパス>

ここで <iOSアプリID> は Firebase プロジェクトで確認できる iOS アプリの ID(1:xxxxxxxxxxxx:ios:yyyyyyyyyyyyyyyyyyyyyy のような形式)です。

CI/CD で運用する場合は、

  • ビルドステップで .xcarchive を生成
  • アーカイブ内の dSYMs ディレクトリを取り出す
  • Firebase CLI コマンドでアップロード

という流れをスクリプト化しておくと、毎回手動でアップロードする手間がなくなります。

NuGet パッケージと SDK を最新に保つ

Crashlytics 本体や、.NET MAUI 向けの Firebase バインディングライブラリも進化を続けています。古いパッケージを使っていると、

  • 新しい Xcode/iOS に追随できておらず、dSYM の扱いで不具合を持っている
  • upload-symbols スクリプトとの整合性が取れていない

といった問題に繋がることがあります。

定期的に次の点を確認しましょう。

  • Firebase 関連の NuGet パッケージ(Crashlytics、Analytics など)が最新か
  • .NET SDK(.NET 7 / 8 等)がサポート期間内の最新パッチレベルか
  • Xcode および Command Line Tools が、サポートされている組み合わせになっているか

開発チームで「Xcode と .NET SDK のサポートバージョン表」を作っておくと、環境差異によるトラブルを減らせます。

dSYM を手動でアップロードする手順(最終手段)

自動アップロードがうまく動いていないときや、過去のビルドのクラッシュを解析したいときは、dSYM を手動でアップロードする必要があります。

Xcode から dSYM を取り出す

  1. Xcode を開き、メニューから Window > Organizer を選択
  2. 該当アプリのアーカイブ(Archives)タブを開く
  3. dSYM をアップロードしたいビルドを選択
  4. Show in Finder をクリックして .xcarchive を Finder で表示
  5. .xcarchive を右クリックして Show Package Contents を選択
  6. 中にある dSYMs フォルダを見つけ、対象の *.app.dSYM を取り出す

この *.app.dSYM を Firebase CLI でアップロードします。

Firebase CLI でアップロードする

firebase crashlytics:symbols:upload \
  --app=&lt;iOSアプリID&gt; \
  "&lt;path/to/MyApp.app.dSYM&gt;"

アップロードが成功すると、Crashlytics 側で数分〜十数分程度処理が走り、そのビルドに紐づくクラッシュログが徐々に復号されていきます。

Crashlytics コンソールでアップロード状態を確認する

設定やスクリプトを変更したら、Crashlytics ダッシュボードで dSYM の状態を必ず確認しましょう。

  • Firebase コンソールで対象プロジェクトを開く
  • Crashlytics を選択
  • 右上の設定(歯車アイコン)から Debug symbol(もしくは類似のメニュー)を開く

ビルドごとに、次のようなステータスが表示されます。

ステータス意味次にやること
MissingdSYM が見つかっていない生成設定とアップロードスクリプトを確認する
ProcessingdSYM を受け取り処理中数分待ってからクラッシュレポートを再確認
CompletedSYM が利用可能で、シンボリケーション済みクラッシュログが行番号付きで閲覧可能

自動アップロードがうまく動いていれば、新しいビルドが Complete になるまでがスムーズに流れるはずです。

よくあるつまずきポイントと対処法

実際に .NET MAUI + Crashlytics を運用していると、次のようなトラブルに遭遇しがちです。

症状主な原因対処方法
dSYM がそもそも生成されないDebugTypeportablenone になっているDebugType=full を Release 向けに設定し、再ビルドする
upload-symbols 実行時に Failed to upload dSYMupload-symbols に実行権限がない、またはネットワーク制限chmod +x で実行権限を付与し、プロキシやファイアウォールも確認する
dSYM アップロードは成功しているのに警告が消えない別バージョン/別ビルド番号の dSYM をアップロードしているビルド番号(CFBundleVersion)と Firebase 上のビルドが一致しているか確認
複数アーキテクチャ混在でアップロードに失敗古い Xcode でビルドしており、dSYM のフォーマットが新仕様と合わないXcode と Command Line Tools を MAUI がサポートする最新版に更新
CI/CD ではクラッシュが解析されないが、ローカルビルドでは問題なしCI スクリプトで dSYM を削除したり、upload-symbols を呼び出していないCI のビルドパイプラインに dSYM の保存とアップロード処理を追加
Crashlytics にクラッシュが届いているのにスタックトレースが「アドレスの羅列」のままdSYM がアップロードされていないか、処理中のままDebug symbol 状態を確認し、必要に応じて手動で対象ビルドの dSYM を再アップロード

上の表を眺めると分かる通り、多くのトラブルは

  • csproj 設定の不足
  • Xcode / CI のスクリプト設定漏れ

のどちらかに分類できます。

CI/CD(App Center・GitHub Actions・Azure DevOps)での運用のコツ

本番運用では、手元の Mac からビルドしてアプリを配布するよりも、CI/CD を使って自動ビルド・自動配布することが多くなります。その場合、Crashlytics への dSYM アップロードも CI パイプラインの中に組み込んでおくと安心です。

典型的なパイプライン構成

例えば GitHub Actions を使う場合を例にすると、次のようなステップ構成が考えられます。

  1. .NET MAUI の iOS ビルド(Release)
  2. Xcode アーカイブの生成(xcodebuild archive
  3. アーカイブから dSYMs を抽出
  4. Firebase CLI で dSYM をアップロード
  5. IPA を TestFlight / App Store にアップロード

このとき、

  • dSYM を アーティファクトとして保存 しておく(後からトラブルシュートに使える)
  • Firebase CLI の認証情報はシークレット管理する

といった運用ルールを決めておくと安心です。

dSYM の保管ポリシーを決めておく

Crashlytics にアップロードした後も、dSYM 自体は手元またはストレージサービス等に保管しておくことをおすすめします。

  • 各ビルド(ビルド番号)ごとに dSYMs を zip で固める
  • CI のアーティファクトとして一定期間保管
  • 必要に応じて長期保管用のストレージに移動

将来 Crashlytics 側で問題が起きた場合でも、dSYM さえ残っていれば別ツールでシンボリケーションし直す可能性が残ります。

今後同じ警告を出さないためのチェックリスト

最後に、.NET MAUI + Firebase Crashlytics で「dSYM ファイルが不足しています」警告を出さないためのポイントをまとめます。

項目チェック内容
csproj 設定DebugType=fullDebugSymbols=true が Release 構成の iOS 向けに設定されているか
Xcode 設定Debug Information Format が「DWARF with dSYM File」、Bitcode が無効になっているか
自動アップロードupload-symbols スクリプトまたは Firebase CLI を用いた dSYM アップロード処理がビルド後に必ず実行されるか
パッケージ更新Firebase 関連 NuGet パッケージと .NET SDK、Xcode がサポート範囲内の最新版か
運用ルールdSYM の保存ポリシー(どこに・どのくらい保管するか)がチーム内で共有されているか

このチェックリストをプロジェクトの README や社内 Wiki にまとめておけば、新しいメンバーが参加したときや環境を移行するときにもスムーズに引き継ぎができます。

まとめ:dSYM はクラッシュ解析の「鍵」、3 ステップを押さえれば怖くない

Firebase Crashlytics の「dSYM ファイルが不足しています」警告は、一見すると何をどうすればよいのか分かりづらいメッセージです。しかし整理してみると、やるべきことはシンプルです。

  • 生成: .NET MAUI プロジェクトで DebugType=full を設定し、Xcode で「DWARF with dSYM File」を選ぶ
  • 保持: CI/CD の途中で dSYM を削除しないようにし、必要に応じてアーティファクトとして保管する
  • アップロード: upload-symbols スクリプトや Firebase CLI で Crashlytics に確実に渡す

この 3 ステップさえ守っておけば、Crashlytics のダッシュボードには行番号付きのクラッシュログが並び、.NET MAUI iOS アプリの品質改善サイクルを高速に回せるようになります。

今まさに「This missing dSYM file is required to process crashes」警告に悩まされている場合は、本記事の手順に沿って設定を見直してみてください。設定がハマった瞬間から、これまで読めなかったクラッシュログが一気に情報を語り始めるはずです。

この記事を書いた人

実務の現場で詰まりがちなポイントを地図にするITブログ「IT trip」を運営。Windows/Office(Teams・Excel)からSQL、サーバ運用、ガジェットまで、再現性のある手順と“なぜそうなるか”を丁寧に解説します。読んだらすぐ試せること、そして迷った人の次の一歩が見えることを大切にしています。

コメント

コメントする

目次