現場で震えるほど役立つ!Crashlyticsで「非致命的エラー」を制し、アプリの品質を爆上げする方法
こんにちは。日夜、システムの「健康状態」と格闘しているエンジニアの皆さん。
多くのエンジニアが「アプリが落ちなければ問題なし」と考えていますが、それは氷山の一角しか見えていない状態です。ユーザーが体験している「ボタンを押しても反応しない」「表示が崩れる」「データが保存されない」といったサイレントな苦痛。これらを引き起こしているのが「非致命的エラー(Non-fatal)」です。
今日は、Firebase Crashlyticsを使って、これらの「隠れた不具合」を根こそぎ検知し、ユーザーから「このアプリ、なぜか使い心地がいい」と言わせるための極意を伝授します。
—
1. なぜ「非致命的エラー」を追う必要があるのか?
Crashlyticsといえば「アプリのクラッシュ検知」というイメージが強いですが、真のプロは「クラッシュしないエラー」にこそ血眼になります。
- 予兆検知: クラッシュに至る直前の「データ整合性の崩れ」をキャッチできれば、未然に防げる。
- ユーザー体験の向上: 「落ちないけれど動かない」という一番ストレスフルな状況を即座に特定できる。
- デバッグの効率化: 「なんか調子が悪い」という曖昧な報告を、スタックトレース付きの確実な証拠に変換できる。
—
2. 最速セットアップ:まずはここから
Firebaseプロジェクトにアプリを登録している前提で、最も重要な基礎セットアップを解説します。
インストール(例:Swift/iOSの場合)
Swift Package Manager経由で追加するのが現在のスタンダードです。
1. Xcodeの `File > Add Packages` に `https://github.com/firebase/firebase-ios-sdk` を追加。
2. `FirebaseCrashlytics` を選択。
3. `AppDelegate` で初期化します。
import FirebaseCore
import FirebaseCrashlytics
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions …) -> Bool {
// Firebaseの初期化
FirebaseApp.configure()
return true
}
}
これで準備完了。では、ここからが本題です。
—
3. 「非致命的エラー」をキャッチする神髄:`recordError`
単純に `try-catch` でエラーを握りつぶしてログを出すだけでは足りません。Crashlyticsに「これは重大な事象である」と教え込む必要があります。
正しい実装パターン
API通信やデータ処理など、失敗する可能性がある箇所で以下のように実装します。
do {
let data = try fetchDataFromAPI()
// 正常処理
} catch let error {
// 【重要】単なるプリントデバッグで終わらせない
// ここでCrashlyticsにエラーを送り込みます
Crashlytics.crashlytics().record(error: error)
// 必要に応じてコンテキスト(なぜ起きたか)を追加
Crashlytics.crashlytics().setCustomValue(“user_id_12345”, forKey: “last_user_id”)
// ユーザーへの通知など
print(“非致命的エラーを捕捉しました: \(error)”)
}
現場で役立つポイント:優先順位の付け方
すべてのエラーを投げるとノイズだらけになります。以下の基準で選別しましょう。
1. 致命的なデータ不整合: データベースの書き込み失敗など、ユーザーデータが壊れる可能性。→ 必ず記録
2. 回復可能な通信エラー: ネットワークオフラインなど、アプリ側でリトライして復帰できるもの。→ 記録不要(またはWarningレベルで記録)
3. ユーザー操作のキャンセル: ユーザーが意図的に閉じたもの。→ 記録不要
—
4. 精度を劇的に高める「カスタムキー」の活用
ただエラーを投げるだけでは「何が起きたか」は分かっても「なぜ起きたか」までは見えません。「その時、ユーザーは何をしていたのか?」を付与するのがプロの流儀です。
func processOrder(orderId: String) {
Crashlytics.crashlytics().setCustomValue(orderId, forKey: “current_order_id”)
// エラーが起きた時、この情報が一緒に送られるため、
// どの注文IDでエラーが多発しているか一瞬で特定できます。
}
これをマスターすれば、バグレポートを見た瞬間に「あ、特定の注文IDだけ処理がタイムアウトしてるな」と確信を持って修正に入れるようになります。
—
5. 最後に:初心者のあなたへ
最初は「エラーをわざわざ自分で投げる」という作業が面倒に感じるかもしれません。ですが、これは「未来の自分を救う保険」です。
アプリがリリースされた後、ユーザーからの「なんか動かない」という問い合わせに怯える日々を過ごすか、Crashlyticsのダッシュボードを見て「あ、このエラーが数件出ているな、今のうちに直しておこう」と先手を打つか。
どちらがエンジニアとして「楽」か、言うまでもありませんよね。
まずは、今書いているコードの中で「本来こうなるはずがない」と確信している箇所に、`recordError` を一つだけ埋め込んでみてください。あなたのアプリの品質は、その一行から劇的に変わり始めます。
応援しています。最高にクールな運用ライフを!