mcpField
A
axiom-testflight-triage

axiom-testflight-triage

github.com/charleswiltgenテスト・品質1.2k179 回インストール今日更新
リポジトリ

axiom-testflight-triage について

axiom-testflight-triageは、Xcode OrganizerでTestFlightのクラッシュやベータ版のフィードバックを調べる開発者向けスキルです。クラッシュの解釈、シンボリケーション、終了レポート、テスターの状況確認を扱います。

主な機能

  1. 01Xcode Organizerでのクラッシュ確認
  2. 02dSYMファイルによるシンボリケーション
  3. 03例外の種類とスタックトレースの解釈
  4. 04クラッシュレポートのない終了の調査
  5. 05テスターのフィードバックと端末情報の確認

活用シーン

  1. 01Organizerでクラッシュ箇所を特定
  2. 02未シンボリケートのクラッシュレポートを分析
  3. 03クラッシュ記録のないアプリ終了を調査
  4. 04ベータ版のフィードバックから発生状況を把握

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/charleswiltgen/axiom --skill axiom-testflight-triage

インストール後、Claude Code で/axiom-testflight-triageを入力して読み込まれたか確認します。

詳細

TestFlight のクラッシュとフィードバックのトリアージ

概要

Xcode Organizer を使用して、TestFlight のクラッシュを調査し、ベータ版のフィードバックを確認するための体系的なワークフローです。基本原則: 修正を書く前にクラッシュを理解してください。15 分のトリアージで、何時間ものデバッグを防げます。

注意すべき兆候 — このスキルを使う場面

  • 「ベータテスターからアプリがクラッシュしたと言われた」
  • 「App Store Connect のメトリクスにクラッシュが表示されるが、調査方法がわからない」
  • 「Organizer のクラッシュログがシンボリケートされていない」
  • 「ユーザーからクラッシュのスクリーンショットが送られてきたが、再現できない」
  • 「アプリが強制終了されたが、クラッシュは発生しておらず、ただ消えてしまった」
  • 「TestFlight のフィードバックに確認したいスクリーンショットがある」

判断フロー — まずはこちら

「ユーザーからクラッシュが報告された」
  1. Xcode Organizer を開きます(Window → Organizer → Crashes タブ)
  2. 左のサイドバーからアプリを選択します
  3. ユーザーが使用していたビルドバージョンを探します
  4. クラッシュはシンボリケートされていますか?
  5. クラッシュの発生箇所を特定できますか?
「アプリが強制終了されたが、クラッシュレポートがない」

すべての終了でクラッシュレポートが生成されるわけではありません。次を確認してください。

  1. Jetsam レポート — メモリプレッシャーによりシステムがアプリを終了した場合
    • Organizer ではクラッシュとは別に表示されます
    • pageOutsの値が大きいか確認します
  2. Watchdog による終了 — メインスレッドが長時間ブロックされた場合
    • 例外コード0x8badf00d(「悪いものを食べた」)
    • 起動中(>20s)またはバックグラウンドタスク中(>10s)に発生します
  3. MetricKit 診断情報 — デバイス上での終了理由
    • アプリへの MetricKit の統合が必要です

→ クラッシュレポートを伴わない終了を参照してください

「TestFlight のフィードバックを確認したい」
  1. Xcode Organizer → Feedback タブ(Crashes の隣)
  2. または App Store Connect → My Apps → [App] → TestFlight → Feedback

→ フィードバックのトリアージワークフローを参照してください


Xcode Organizer の使い方

Organizer を開く

Window → Organizer(または Xcode で ⌘⇧O)

UI レイアウト
┌─────────────────────────────────────────────────────────────────┐
│ [Toolbar: Time Period ▼] [Version ▼] [Product ▼] [Release ▼]   │
├──────────┬──────────────────────────┬───────────────────────────┤
│ Sidebar  │     Crashes List         │       Inspector           │
│          │                          │                           │
│ • Crashes│  ┌─────────────────────┐ │  Distribution Graph       │
│ • Energy │  │ syncFavorites crash │ │  ┌─────────────────────┐  │
│ • Hang   │  │ 21 devices • 7 today│ │  │ ▄ ▄▄▄ v2.0          │  │
│ • Disk   │  └─────────────────────┘ │  │ ▄▄▄▄▄ v2.0.1        │  │
│ Feedback │  ┌─────────────────────┐ │  └─────────────────────┘  │
│          │  │ Another crash...    │ │                           │
│          │  └─────────────────────┘ │  Device Distribution      │
│          │                          │  OS Distribution          │
│          ├──────────────────────────┤                           │
│          │     Log View             │  [Feedback Inspector]     │
│          │  (simplified crash view) │  Shows tester feedback    │
│          │                          │  for selected crash       │
└──────────┴──────────────────────────┴───────────────────────────┘
主な機能
機能説明
Speedy DeliveryTestFlight のクラッシュが発生から間もなく配信されます(毎日ではありません)
Year of History期間でクラッシュを絞り込み、月ごとの傾向を確認できます
Product FilterApp Clip、watch アプリ、拡張機能、メインアプリで絞り込めます
Version Filter特定のビルドまで詳しく確認できます
Release FilterTestFlight と App Store のクラッシュを分けて表示します
Share Buttonチームメンバーとクラッシュのリンクを共有できます
Feedback Inspector選択したクラッシュに関するテスターのコメントを確認できます
クラッシュ項目のバッジ

一覧のクラッシュには、発生元を示すバッジが表示されます。

バッジ意味
App ClipApp Clip で発生したクラッシュ
WatchwatchOS コンパニオンで発生したクラッシュ
Extension共有拡張機能やウィジェットなどで発生したクラッシュ
(none)メインの iOS アプリ
トリアージの質問ワークフロー

コードを詳しく調べる前に、次の質問を自分に問いかけてください(WWDC より)。

質問 1 — この問題はいつから発生していますか

→ 右側にあるインスペクタのグラフ領域を確認します → グラフの凡例に、影響を受けているバージョンが表示されます → クラッシュが最初に発生した時期を確認します

質問 2 — 本番環境にも影響していますか、それとも TestFlight だけですか

→ ツールバーのRelease フィルタを使用します → App Store のクラッシュだけを表示するには「Release」を選択します → ベータ版のクラッシュだけを表示するには「TestFlight」を選択します

質問 3 — ユーザーは何をしていましたか

→ Feedback Inspector(右側のパネル)を開きます → テスターが操作内容を説明したコメントを確認します → 状況を示す手がかりとして、ネットワークの状態、バッテリー残量、ディスク容量を確認します

Feedback Inspector の使用

クラッシュに関連付けられた TestFlight フィードバックがある場合、クラッシュ一覧にフィードバックアイコンが表示されます。クリックすると Feedback Inspector が開きます。

各フィードバック項目には、次の情報が表示されます。

項目重要な理由
バージョン/ビルドテスターが実行していた正確なビルドを確認できます
デバイスモデルデバイス固有のクラッシュ(古いデバイス、特定の画面サイズなど)を確認できます
バッテリー残量バッテリー残量が少ないと、アプリの動作に影響することがあります
空きディスク容量ディスク容量が少ないと、書き込みに失敗することがあります
ネットワークの種類モバイル通信か Wi-Fi か、接続の問題があったかを確認できます
テスターのコメント何が起きたかについての説明を確認できます

WWDC での分析例: あるテスターは、「トンネルを通っているときにお気に入りボタンを押しました。数秒後にクラッシュしました」とコメントしました。これにより、ネットワークのタイムアウトの問題が明らかになりました。通信状態が悪い環境では、10 秒のタイムアウトが短すぎたためにクラッシュが発生していたのです。

プロジェクトでクラッシュを開く
  1. 一覧からクラッシュを選択します
  2. Open in Project ボタンをクリックします
  3. Xcode が開き、次の内容が表示されます。
    • デバッグナビゲーターにバックトレースが表示されます
    • エディターでクラッシュが発生した正確な行が強調表示されます
クラッシュの共有
  1. クラッシュを選択します
  2. ツールバーの Share ボタンをクリックします
  3. 次のオプションがあります。
    • チームと共有するリンクをコピーする
    • To Do リストに追加する
  4. チームメイトがリンクをクリックすると、Organizer が開き、該当するクラッシュが表示されます

シンボリケーションのワークフロー

クラッシュがシンボリケーションされない理由

クラッシュレポートには、dSYM ファイル(デバッグシンボルファイル)と照合されるまで、生のメモリアドレスが表示されます。次の条件を満たすと、Xcode が自動的に処理します。

  • Xcode でビルドをアーカイブしている(コマンドラインのみでのビルドではない)
  • 配布時に「シンボルを Apple にアップロード」が有効になっていた
  • dSYM が Spotlight にインデックスされている
簡易チェック:シンボリケーションされていますか?

Organizer でスタックトレースを確認します。

表示内容状態
0x0000000100abc123未シンボリケーション — dSYM が必要です
MyApp.ViewController.viewDidLoad() + 45シンボリケーション済み — 分析できます
システムフレームはシンボリケーション済み、アプリフレームは未シンボリケーション一部のみシンボリケーション済み — dSYM が見つかりません
手動でのシンボリケーション

自動シンボリケーションに失敗した場合:

# 1. Find the crash's build UUID (shown in crash report header)
#    Look for "Binary Images" section, find your app's UUID

# 2. Find matching dSYM
mdfind "com_apple_xcode_dsym_uuids == YOUR-UUID-HERE"

# 3. If not found, check Archives
ls ~/Library/Developer/Xcode/Archives/

# 4. Symbolicate a specific address
xcrun atos -arch arm64 \
  -o MyApp.app.dSYM/Contents/Resources/DWARF/MyApp \
  -l 0x100000000 \
  0x0000000100abc123

# 5. Symbolicate an entire crash log (parse + symbolicate in one step)
# Note: crashlog is an LLDB Python script, not a compiled tool.
# Works via xcrun but may not be available in all Xcode configurations.
xcrun crashlog MyCrash.ips

atos と crashlog の違い:個別のアドレスには atos を使用します(常に利用できます)。クラッシュレポート全体を一度に解析してシンボリケーションするには crashlog を使用します。Binary Images セクション全体を処理し、すべてのアドレスを自動的に解決します。

よくあるシンボリケーションの失敗
症状原因対処方法
システムフレームは正常、アプリフレームは 16 進数アプリの dSYM が見つかりませんArchives フォルダーで dSYM を探すか、シンボルを含めて再アーカイブします
何もシンボリケーションされないクラッシュレポートと dSYM の UUID が一致しませんUUID が一致することを確認し、まったく同じコミットから再ビルドします
atos で「ファイルがありません」と表示されるdSYM が Spotlight のインデックスにありませんmdimport /path/to/MyApp.dSYM を実行します
dSYM がどこにも見つからないシンボルなしでアーカイブされていますビルド設定で「Debug Information Format = DWARF with dSYM」を有効にします
シンボリケーションの問題を防ぐ
# Verify dSYM exists after archive
ls ~/Library/Developer/Xcode/Archives/YYYY-MM-DD/MyApp*.xcarchive/dSYMs/

# Verify UUID matches
dwarfdump --uuid MyApp.app.dSYM

クラッシュレポートを読む

重要なフィールド(実際に役立つ情報)
項目内容
Exception Typeクラッシュのカテゴリ(EXC_BAD_ACCESS、EXC_CRASH など)
Exception Codesエラーの詳細(KERN_INVALID_ADDRESS はヌルポインターを示します)
Termination Reasonシステムがプロセスを終了させた理由
Crashed Threadクラッシュしたスレッド(Thread 0 はメインスレッド)
Application Specific Information多くの場合、実際のエラーメッセージが含まれます
Binary Images読み込まれたフレームワーク(原因となったサードパーティ製コンポーネントの特定に役立ちます)
スタックトレースを読む

クラッシュしたスレッドのスタックトレースは、上から下へ読みます。

  • フレーム 0 = クラッシュが発生した場所(最も具体的な位置)
  • 下位のフレーム = それを呼び出したもの(呼び出しチェーン)
  • 自分のコードを探す = アプリ/フレームワーク名を含むフレーム
Thread 0 Crashed:
0   libsystem_kernel.dylib    __pthread_kill + 8        ← System code
1   libsystem_pthread.dylib   pthread_kill + 288        ← System code
2   libsystem_c.dylib         abort + 128               ← System code
3   MyApp                     ViewController.loadData() ← YOUR CODE (start here)
4   MyApp                     ViewController.viewDidLoad()
5   UIKitCore                 -[UIViewController _loadView]

フレーム 3 から始めます — 自分のコードで最初のフレームです。下へ進み、呼び出しチェーンを把握します。

例:実際のクラッシュを読み解く
Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000010

Thread 0 Crashed:
0   MyApp    0x100abc123 UserManager.currentUser.getter + 45
1   MyApp    0x100abc456 ProfileViewController.viewDidLoad() + 123
2   UIKitCore 0x1a2b3c4d5 -[UIViewController loadView] + 89

解説:

  • EXC_BAD_ACCESS と KERN_INVALID_ADDRESS = 無効なメモリにアクセスしようとしました
  • アドレス 0x10 = 非常に低いアドレスで、ほぼ確実に nil のデリファレンスです
  • currentUser.getter でクラッシュ = nil だったプロパティにアクセスしています
  • ProfileViewController.viewDidLoad() から呼び出し = ビューのセットアップ中です

考えられる原因: nil だったオプショナルを強制アンラップしたか、解放済みのオブジェクトにアクセスした可能性があります。


よくあるクラッシュパターン

EXC_BAD_ACCESS(SIGSEGV / SIGBUS)

意味: 自分が所有していないメモリにアクセスしました。

Swift でよくある原因:

パターン例修正方法
nil の強制アンラップuser!.nameguard let または if let を使用します
解放済みオブジェクト解放後にエスケープクロージャ内から self にアクセス[weak self] を使用します
配列の範囲外アクセスarray[index](index >= count の場合)先に範囲を確認します
未初期化ポインター不正なポインターを使った C との相互運用使用前にポインターを検証します
// Before (crashes if user is nil)
let name = user!.name

// After (safe)
guard let user = user else {
    logger.warning("User was nil in ProfileViewController")
    return
}
let name = user.name
EXC_CRASH(SIGABRT)

意味: アプリが意図的に自身を終了しました。

よくある原因:

パターンクラッシュレポート内の手がかり
fatalError() / preconditionFailure()Application Specific Info にあるアサーションメッセージ
キャッチされない Objective-C 例外レポート内の NSException の型と理由
Swift ランタイムエラー「Fatal error: ...」というメッセージ
デッドロックの検出現在のキューに対する dispatch_sync

デバッグのヒント: 「Application Specific Information」セクションを確認してください。通常、実際のエラーメッセージが含まれています。

ウォッチドッグによる終了(0x8badf00d)

意味: メインスレッドが長時間ブロックされ、システムがアプリを強制終了しました。

制限時間:

状況制限時間
アプリの起動約 20 秒
バックグラウンドタスク約 10 秒
アプリがバックグラウンドに移行するとき約 5 秒

よくある原因:

  • メインスレッドでの同期ネットワークリクエスト
  • メインスレッドでの同期ファイル I/O
  • キュー間のデッドロック
  • UI をブロックする負荷の高い計算
// Before (blocks main thread — will trigger watchdog)
let data = try Data(contentsOf: largeFileURL)
processData(data)

// After (offload to background)
Task.detached {
    let data = try Data(contentsOf: largeFileURL)
    await MainActor.run {
        self.processData(data)
    }
}
Jetsam(メモリ圧迫による強制終了)

意味: メモリを解放するためにシステムがアプリを終了しました。クラッシュレポートはなく、アプリが突然終了します。

症状:

  • クラッシュせずにアプリが「消える」
  • Organizer に Jetsam レポートが表示される(クラッシュとは別)
  • レポート内の pageOuts の値が高い
  • 写真や動画の処理中、または大量のデータを扱う処理中によく発生する

調査方法:

  1. Instruments → Allocations でプロファイルします
  2. 報告された処理中にメモリ使用量が急増していないか確認します
  3. サイズ制限なしで画像をキャッシュしていないか確認します
  4. メモリ上に保持されている大きなデータ構造がないか確認します

よくある修正方法:

  • バッチ処理に autoreleasepool を使用します
  • メモリ制限付きの画像キャッシュを実装します
  • 大きなファイルは全体を読み込まず、ストリーミングします
  • バックグラウンドに移行したときに、大きなオブジェクトへの参照を解放します

クラッシュレポートを伴わない終了

ユーザーから「アプリが突然閉じた」と報告されたものの、クラッシュが見つからない場合:

Terminations Organizer

Terminations Organizer(Crashes とは別)では、プログラミング上のクラッシュではないアプリ終了の傾向を確認できます。

Window → Organizer → Terminations(サイドバー内)

終了カテゴリ意味
起動タイムアウトアプリの起動に時間がかかりすぎました
メモリ制限システムのメモリ上限に達しました
CPU 制限(バックグラウンド)バックグラウンド中の CPU 使用量が多すぎました
バックグラウンドタスクのタイムアウトバックグラウンドタスクが制限時間を超えました

重要なポイント: 終了率を以前のバージョンと比較して、リグレッションを見つけます。リリース後にメモリによる終了が急増した場合、メモリリークまたはメモリ使用量の増加が考えられます。

Jetsam の確認
  1. Organizer → アプリを選択 → 「Disk Write Diagnostics」または「Hang Diagnostics」を探します
  2. これらはクラッシュではなく、システムによって開始された終了です
バックグラウンドでの終了の確認

アプリはバックグラウンドで次の理由により終了することがあります。

  • メモリ圧迫(jetsam)
  • バックグラウンド中の CPU 使用量
  • バックグラウンドタスクのタイムアウト
ユーザーに確認する

レポートがない場合:

  1. 「アプリが終了したとき、フォアグラウンドで実行されていましたか?」
  2. 「エラーメッセージは表示されましたか?」
  3. 「発生する直前に何をしていましたか?」
  4. 「アプリを開いてから、どのくらい経っていましたか?」
MetricKit で診断を改善する

MetricKit のクラッシュ診断は、日次で集約されるのではなく、次回のアプリ起動時に配信されるようになりました。これにより、クラッシュデータをより早く確認できます。

import MetricKit

class MetricsManager: NSObject, MXMetricManagerSubscriber {

    static let shared = MetricsManager()

    func startListening() {
        MXMetricManager.shared.add(self)
    }

    func didReceive(_ payloads: [MXMetricPayload]) {
        // Process performance metrics
    }

    func didReceive(_ payloads: [MXDiagnosticPayload]) {
        for payload in payloads {
            // Crash diagnostics — delivered on next launch
            if let crashDiagnostics = payload.crashDiagnostics {
                for crash in crashDiagnostics {
                    // Process crash diagnostic
                    print("Crash: \(crash.callStackTree)")
                }
            }

            // Hang diagnostics
            if let hangDiagnostics = payload.hangDiagnostics {
                for hang in hangDiagnostics {
                    print("Hang duration: \(hang.hangDuration)")
                }
            }
        }
    }
}

MetricKit と Organizer の使い分け:

用途ツール
TestFlight のクラッシュをすばやくトリアージするOrganizer(より高速で視覚的)
プログラムによるクラッシュ分析MetricKit
カスタムのクラッシュレポート連携MetricKit
バージョン間の終了傾向Terminations Organizer

Claude を活用した解釈

Crash Analyzer エージェントを使用する

自動クラッシュ分析には、crash-analyzer エージェントを使用します。

/axiom:analyze-crash

または、自然な言葉で実行します:

  • 「このクラッシュログを分析して」
  • 「この .ips ファイルを解析して:~/Library/Logs/DiagnosticReports/MyApp.ips」
  • 「アプリがクラッシュした理由は?レポートはこちらです……」

エージェントは次の処理を行います:

  1. クラッシュレポートを解析します(JSON の .ips 形式またはテキストの .crash 形式)
  2. シンボル化の状態を確認します
  3. クラッシュのパターン(ヌルポインター、Swift ランタイム、ウォッチドッグ、jetsam など)ごとに分類します
  4. 具体的な次の手順を含む、実行可能な分析を生成します
効果的なプロンプト

基本的な解釈:

Here's a crash report from my iOS app. Help me understand:
1. What type of crash is this?
2. Where in my code did it crash?
3. What's the likely cause?

[paste full crash report]

コンテキストを含める場合(より良い結果):

My TestFlight app crashed. Here's what I know:

- User was [describe action, e.g., "tapping the save button"]
- iOS version: [from crash report]
- Device: [from crash report]

Crash report:
[paste full crash report]

The relevant code is in [file/class name]. Help me understand the cause.
含める情報
含める情報理由
クラッシュレポート全体部分的なレポートではコンテキストが失われます
ユーザーが行っていた操作コードパスを絞り込むのに役立ちます
関連するコードスニペットクラッシュが起きた箇所が分かっている場合に役立ちます
iOS のバージョンとデバイスデバイスや OS に固有のクラッシュもあります
Claude が支援できること
  • 例外の種類とコードの解釈
  • スタックトレースから原因として考えられるものの特定
  • 見慣れないシステムフレームの説明
  • ログを追加する場所の提案
  • 修正パターンの提案
判断が必要なこと
  • 提案された修正がアーキテクチャに適しているかどうか
  • クラッシュをローカルで再現する方法
  • 他のバグと比べた優先度
  • リグレッションか、以前から存在する問題かどうか

フィードバックのトリアージワークフロー

フィードバックの確認場所

Xcode Organizer(推奨): 「Window」→「Organizer」→アプリを選択→「Feedback」タブ

App Store Connect: 「My Apps」→[App]→「TestFlight」→「Feedback」

各フィードバック項目の内容
項目説明
スクリーンショットユーザーが見た画面(多くの場合、最も有用な情報です)
テキストコメント問題についてのユーザーの説明
デバイス/OSiPhone のモデルと iOS のバージョン
アプリのバージョン該当する TestFlight ビルド
タイムスタンプ送信日時
トリアージワークフロー
  1. 新しい順に並べ替える — 特定の問題を調査している場合を除き、新しいものから確認します
  2. スクリーンショットを確認する — 視覚的な問題はすぐに分かります
  3. コメントを読む — ユーザーの説明とコンテキストを確認します
  4. バージョンを確認する — 新しいビルドで修正されていますか?
  5. 分類する:
カテゴリアクション
🐛 バグ調査し、課題を登録して、修正の優先度を決めます
💡 機能リクエスト有用であればバックログに追加します
❓ 不明瞭追加のコンテキストがないと対応できません
✅ 想定どおりの動作UX に関する混乱を示している可能性があります
制限事項
  • 直接返信できない — TestFlight ではフィードバックへの返信をサポートしていません
  • スクリーンショットのみ — 動画録画には対応していません
  • コンテキストが限られる — ユーザーは、何をしようとしていたのかを説明しないことがよくあります
MCP を活用したフィードバックへのアクセス

asc-mcp が設定されている場合、クラッシュ診断とテスターのデータにプログラムからアクセスできます。

タスクasc-mcp ツールワーカー
最近のビルドを一覧表示するbuilds_listbuilds
ビルドをテストしたユーザーを確認するbuilds_get_beta_testersbuild_beta
ビルドのクラッシュシグネチャを取得するmetrics_build_diagnosticsmetrics
クラッシュログをダウンロードするmetrics_get_diagnostic_logsmetrics
修正版をテスターに配布するbeta_groups_add_buildsbeta_groups
新しいビルドをテスターに通知するbuilds_send_beta_notificationbuild_beta

制限事項:TestFlight のテキストフィードバックとスクリーンショットは、App Store Connect API からは利用できません。フィードバックの内容を確認するには、Xcode Organizer または ASC の Web ダッシュボードを使用してください。

セットアップ:/skill axiom-asc-mcp

コンテキストをさらに得る

フィードバックが不明瞭で、テスターに連絡できる場合は、次の方法を試してください。

  • TestFlight グループのメールを通じて連絡する
  • より詳細な情報を収集できるアプリ内フィードバック機能を追加する
  • TestFlight のメモに再現手順を尋ねるプロンプトを含める

プレッシャーのかかる状況

シナリオ 1:「VIP ユーザーからアプリが頻繁にクラッシュすると言われたが、クラッシュレポートが見つからない」

プレッシャー: 重要な関係者からの報告で証拠はなく、「こちらでは問題ありません」と片付けたくなる状況です。

適切な対応:

  1. TestFlight を使用していることを確認します(App Store 版や開発版ではないことを確認します)。
  2. 診断データの共有に同意していることを確認します(設定 → プライバシー → 解析)。
  3. jetsam レポートを確認します(クラッシュレポートを残さずに終了したケース)。
  4. そのユーザーのデバイスと OS の組み合わせに関するクラッシュレポートを確認します。
  5. 具体的な再現手順を尋ねます。
  6. それでも見つからない場合は、問題の画面収録を依頼します。

回答テンプレート:

「クラッシュレポートを確認しましたが、ご説明いただいた内容に該当するクラッシュはまだ見つかっていません。調査のため、次の点を確認させてください。(1)TestFlight 版を実行していることを確認していただけますか?(2)具体的にはどのようなことが起きますか?アプリが突然終了する、フリーズする、エラーが表示される、のいずれでしょうか?(3)その直前に何をしていましたか?問題を特定する手がかりになります。」

重要な理由: 「こちらでは問題ありません」という対応は信頼を損ないます。片付ける前に、徹底的に調査してください。

シナリオ 2:「最新の TestFlight ビルドの後にクラッシュ率が急上昇したので、すぐに修正したい」

プレッシャー: 時間に追われ、コード変更に基づいて修正を推測したくなる状況です。

適切な対応:

  1. Organizer → Crashes を開き、新しいビルドに絞り込みます。
  2. 例外タイプごとにクラッシュをグループ化します(最も多いシグネチャを探します)。
  3. 発生頻度が最も高いクラッシュを特定します。
  4. シンボリケートして、クラッシュレポートを最後まで読みます。
  5. 修正を書く前に原因を理解します。
  6. 可能であれば、ローカルで再現します。
  7. 推測ではなく、確認できた原因を修正します。

重要な理由: 急いで推測すると、新たなバグを持ち込んだり、真の問題を見逃したりすることがよくあります。適切なトリアージに 15 分かければ、何時間もの見当違いなデバッグを防げます。

シナリオ 3:「クラッシュレポートはシンボリケート済みだが、まだ内容が理解できない」

プレッシャー: 無視するか、効果を期待して手当たり次第に変更したくなる状況です。

適切な対応:

  1. コンテキストを添えて、クラッシュレポート全体を Claude に貼り付けます。
  2. 単に「これを修正して」と頼むのではなく、内容の解釈を求めます。
  3. よく知らない例外タイプを調べます。
  4. 調べてもまだ不明な場合は、クラッシュ箇所の周辺にログを追加します。
func suspectFunction() {
    logger.debug("Entering suspectFunction, state: \(debugDescription)")
    defer { logger.debug("Exiting suspectFunction") }

    // ... existing code ...
}
  1. 計測コードを追加したビルドを TestFlight に配布します。
  2. より詳しいコンテキストを得られる状態で再現されるのを待ちます。

重要な理由: 推測するより理解することが大切です。憶測するよりログを取ることが大切です。手当たり次第の変更を配布するのではなく、「さらに情報が必要です」と伝えても問題ありません。


クイックリファレンス

Organizer のキーボードショートカット
アクションショートカット
Organizer を開く⌘⇧O(Xcode から)
更新する⌘R
よくある例外コード
コード意味
KERN_INVALID_ADDRESSNULL ポインター/不正なメモリアクセス
KERN_PROTECTION_FAILUREメモリ保護違反
0x8badf00dウォッチドッグタイムアウト(メインスレッドのブロック)
0xdead10ccデッドロックの検出
0xc00010ff熱イベント(デバイスの過熱)
クラッシュレポートのセクション
セクション内容
ヘッダーアプリ情報、デバイス、OS、日付
例外情報クラッシュの種類とコード
終了理由システムがプロセスを終了した理由
発生したスレッドクラッシュしたスレッド
アプリケーション固有情報エラーメッセージ、アサーション
スレッドのバックトレースすべてのスレッドのスタックトレース
バイナリイメージ読み込まれたフレームワークとアドレス

リソース

WWDC: 2018-414, 2020-10076, 2020-10078, 2020-10081, 2021-10203, 2021-10258

ドキュメント: /xcode/diagnosing-issues-using-crash-reports-and-device-logs, /xcode/examining-the-fields-in-a-crash-report, /xcode/adding-identifiable-symbol-names-to-a-crash-report, /xcode/identifying-the-cause-of-common-crashes, /xcode/identifying-high-memory-use-with-jetsam-event-reports

スキル: axiom-memory-debugging, axiom-xcode-debugging, axiom-swift-concurrency, axiom-lldb(再現して対話的に調査), axiom-asc-mcp(ASC へのプログラムによるアクセス)

エージェント: crash-analyzer(クラッシュログの自動解析と分析)

コメント