個人開発の iOS アプリで Crashlytics を使わずクラッシュを監視する
AI 主体で執筆「個人開発でも Crashlytics は入れるべきか?」という問いに、しばらく悩んでいました。結論として、60d Memo の v1.0 リリースでは Crashlytics を入れず、Apple 公式のチャネルだけで運用を回すことにしました。この記事では、その体制と、あとから Crashlytics を入れる判断基準をまとめます。
前提:なぜ Crashlytics を入れなかったのか
Firebase Crashlytics は無料で強力ですが、個人開発のアプリに入れる前には少し立ち止まりたい理由があります。
- SDK 依存が増える。Firebase iOS SDK はバイナリサイズ・起動時間に非ゼロの影響を与える。
- データ送信先が Google になる。App Privacy Details とプライバシーポリシーの更新が必要になる。
- 個人情報が誤って送られないよう注意が要る。Crashlytics の
setCustomKeyやカスタムログは便利だが、メモ本文のような PII を混入させない運用ルールが必要。 - dSYM アップロードの自動化が必要(Xcode Cloud や CI からのアップロード)。
60d Memo は「メモをユーザー自身の Google ドライブに保存する」設計で、サーバー側にメモ内容を送らないことをアプリの価値として謳っています。ここに Crashlytics の送信経路を追加すると、説明責任が一段重くなる。まずは Apple 公式のチャネルで運用を立ち上げ、必要になったら Crashlytics を足す、という順序にしました。
誤解のないように: Crashlytics が悪いという話ではありません。MAU が一定を超えたり、非致命的なエラーを集計したくなったら導入を検討します(後述)。本稿は「最初の段階で入れるか?」に対する答えです。
公式チャネル 5 つの役割分担
Apple が提供する監視チャネルは 5 つあります。それぞれ役割が違うので、全部を合わせて初めて全体像が見えます。
| チャネル | 何が見えるか | 確認頻度(通常) | 確認頻度(リリース直後) |
|---|---|---|---|
| Xcode Organizer → Crashes | TestFlight / App Store ビルドのクラッシュレポート(dSYM 自動シンボリケート済) | 週 1 | 毎日 |
| ASC → TestFlight → フィードバック | ベータユーザーからのスクリーンショット付きフィードバック | 週 1 | 毎日 |
| ASC → App Analytics → クラッシュ | クラッシュフリーセッション率・影響セッション数の推移 | 月 1 | 週 2 |
| App Store カスタマーレビュー | レビュー経由のバグ報告(星 1〜2 は要確認) | 週 1 | 毎日 |
| メール(アプリ内フィードバック) | アプリ内「フィードバックを送る」からの直接報告 | 受信時 | 受信時 |
「リリース直後」は App Store 公開から 1〜2 週間を指します。クラッシュ率が落ち着くまでは毎日確認する、という運用です。
Xcode Organizer が一番頼りになる
iOS 14 以降、ユーザーがデバイスの設定で「App デベロッパと共有」を有効にしていれば、TestFlight と App Store 配布のクラッシュレポートが自動で Organizer に集まります。dSYM は Apple 側でシンボリケートされるため、個人開発者でも追加の手間はほぼゼロです。
見るべき箇所
- Xcode → Window → Organizer
- 左サイドバーで Crashes を選択
- 上部の App を対象に、Version / Build で絞り込み
- 左ペインのクラッシュグループをクリック → 右ペインにスタックトレース・影響台数・OS バージョン分布
- Open in Project でソースにジャンプ
dSYM が見つからないとき
- Xcode Cloud 経由のビルドは自動アップロード。
- 手動 Archive の場合は Organizer の Distribute App 経由で配布したビルドに dSYM が紐づく。
- なければ App Store Connect → アプリ → ビルド → ダウンロード可能な dSYM から取得し、Organizer に手動で追加。
公式ドキュメント: Diagnosing issues using crash reports and device logs(Apple Developer)。Organizer の見方はここがまとまっています。
App Store Connect:数値のトレンドを見る
Organizer は個別のクラッシュを見るのに強く、ASC の App Analytics は全体の傾向を見るのに強い。両方見ます。
1. TestFlight フィードバック
- App Store Connect → 対象アプリ
- 左サイドバー TestFlight → フィードバック
- スクリーンショットタブ・クラッシュタブを巡回
重要なものは手元にキャプチャを保存し、GitHub Issue 化しておくと後で追跡できます。
2. App Analytics のクラッシュ指標
ASC → 対象アプリ → アプリ分析(App Analytics) → 指標 → クラッシュで、日次のクラッシュフリーセッション率が見られます。しきい値は後述します。
3. カスタマーレビュー
ASC → 対象アプリ → 評価とレビューで、ストアフロント別にレビューを確認。星 1〜2 は「バグ報告」として扱い、該当時期のクラッシュレポートと突き合わせます。
重大度の判定基準(Sev 1〜4)
「何を最優先で直すか」を迷わないために、事前に重大度の表を作っておきます。個人開発だと往々にして「全部 Sev 1」になりがちなので、意図的に Sev 3/Sev 4 を許容する基準が肝です。
| 重大度 | 条件 | 対応速度 |
|---|---|---|
| Sev 1: 致命的 | 起動直後クラッシュ・データ破損・サインイン不能・10% 以上のセッションに影響 | 24h 以内にホットフィックス |
| Sev 2: 高 | 主要機能が一部使えない・1〜10% 影響・特定 OS で再現 | 1 週間以内に修正リリース |
| Sev 3: 中 | 限定的な条件下・< 1% 影響・回避策あり | 次回マイナーで対応 |
| Sev 4: 低 | 単発・再現困難・体感影響なし | バックログで様子見 |
ホットフィックスのフロー(Sev 1/Sev 2)
発見から 2 時間以内
- GitHub Issue を作成(例:
gh issue create --title "[Crash] …" --label "bug,P0: critical") - ローカル・シミュレータで再現を試みる(無理なら推測でも進める)
- 重大度を判定
- 必要なら App Store Connect の「お知らせ」や SNS で一次連絡
修正から配布まで
- ブランチ
fix/{issue}-hotfix-vX.Y.1を main から切る - 最小スコープで修正コミット
- ローカルで
xcodebuild testを必ず走らせる - PR → 自分で diff を再読してから merge
MARKETING_VERSIONを 1 つ上げる(例:1.0→1.0.1)- Xcode Cloud / Archive で TestFlight に上げる
- App Store Connect で Expedited Review(審査促進)を申請(理由: critical bug fix)
- 審査通過後、段階配信ではなく即時 100%で配信開始
事後対応
- クラッシュ率が回復したか 24h・48h で確認
- ポストモーテムを
docs/postmortem-vX.Y.Z.mdに残す(再発防止策込み) - 同類リスクを TODO にチェック項目として追加
Expedited Review について: Apple は濫用を嫌います。本当にユーザー影響の大きいバグ修正のときだけ使うこと。理由欄には 具体的な影響範囲(何% のユーザーが起動できない、など)を書くと通りやすい、という経験則があります。
手動運用のしきい値
SaaS のアラートがない代わりに、カレンダーリマインダーで運用します。
- 毎週月曜 9:00: Xcode Organizer の Crashes を確認(5 分)
- 毎月 1 日: ASC のクラッシュ率トレンドを確認(10 分)
- リリース当日・翌日・3 日後・1 週間後: フルチェック(Organizer + Analytics + Reviews + Feedback)
| メトリクス | 警戒値 | 対応 |
|---|---|---|
| クラッシュフリーセッション率 | < 99.5%(連続 2 日) | Sev 2 として調査開始 |
| クラッシュフリーセッション率 | < 99.0% | Sev 1 として即時調査 |
| 単一クラッシュグループの影響台数 | 10 台以上 | Sev 2 以上で対応 |
| ★1〜2 のレビューが急増 | 1 日 3 件以上 | バグ起因か確認 |
数値は一般的な目安です。アプリの性質(決済を扱うか、命に関わるか等)によって厳しく/緩く調整してください。
Crashlytics を入れる判断基準
将来 Crashlytics を検討するとき、以下のいずれかを満たしたら導入を考えます。
- MAU が 1,000 を超える(手動巡回だと取りこぼしが出始める規模の目安)
- Apple 公式チャネルでは再現条件が掴めないクラッシュが複数発生する(カスタムキーで状況を記録したい)
- 非致命的エラー(API エラー・同期失敗など)を集計したくなる(
recordErrorが欲しい) - ANR(応答なし)の検知が必要になる
逆に、Sev 1 のクラッシュを見逃す頻度が Organizer の週 1 巡回で十分コントロールできているうちは、Crashlytics は要らない、と割り切っています。
プライバシーに関する注意
Apple 公式のクラッシュレポートは「App デベロッパと共有」をユーザーがオプトインした場合にのみ送信されます。それでもレポートにはスタックトレースや端末情報が含まれるので、ユーザーが入力したテキスト(メモ本文等)がスタックに混入しないコード設計が望ましいです。
- ログやエラーメッセージに本文を含めない(ID やハッシュ値にとどめる)
preconditionFailureやfatalErrorのメッセージを丁寧に書く(ユーザー入力を直接連結しない)- Crashlytics を後から入れる場合は、カスタムキーに PII を入れない運用ルールを先に決めてから SDK を入れる
まとめ
- 個人開発の初期段階なら、Xcode Organizer + ASC + TestFlight + レビュー + メールの公式 5 チャネルで監視は回る
- 事前に Sev 1〜4 の重大度表とホットフィックス フローを書いておくと、いざという時に迷わない
- 手動運用はカレンダーリマインダーで代替。しきい値(例: クラッシュフリー < 99.5%)を決めておく
- Crashlytics は「MAU/非致命的エラー集計/ANR/再現困難クラッシュ」のいずれかが効くフェーズで検討する
- どの監視体制でも、個人情報がクラッシュログに混入しないコード設計が最初に来る