[Swift5]Firebase Crashlyticsを設定して使用してみる
導入手順
-
Googleアナリティクスを有効にする (推奨)。
クラッシュに遭遇していないユーザー数の表示、パンくずリストのログ、ベロシティ アラートなどの機能を利用するには、Firebase プロジェクトで Google アナリティクスを有効にする必要がある。
-
Firebase コンソールの [Crashlytics] を有効にする
-
アプリに Firebase Crashlytics SDK を追加する
-
Crashlyticsを初期化する
Crashlytics を初期化するために、実行スクリプトをプロジェクトのBuild Phaseに追加する。実行スクリプトを使用すると、アプリがクラッシュするたびにXcodeが自動的にプロジェクトのdSYMファイルをアップロードするため、Crashlyticsは自動的にクラッシュレポートを生成できる。
Xcodeのプロジェクトの[Build Phases]タブを選択し、+ > [New Run Script Phase]を選択し、Run Scriptに以下を記入する。
${PODS_ROOT}/FirebaseCrashlytics/run
次に、アプリのdSYMファイルとInfo.plist の場所を指定するために以下をinput Filesに記入する。
${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Resources/DWARF/${TARGET_NAME}
$(SRCROOT)/$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)
- プロジェクトを実行し、強制的にクラッシュさせて設定を完了する
実際にCrashlyticsが設定されているかをテストする必要があるため、アプリを実行して強制的にクラッシュさせる。
ドキュメントでは、以下のコードを追加して強制的にクラッシュさせている。ただし、ボタンが見づらいので位置と背景色は調整した。
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let button = UIButton(type: .roundedRect)
button.frame = CGRect(x: 50, y: 100, width: 100, height: 30)
button.backgroundColor = .red
button.setTitle("Crash", for: [])
button.addTarget(self, action: #selector(self.crashButtonTapped(_:)), for: .touchUpInside)
view.addSubview(button)
}
@IBAction func crashButtonTapped(_ sender: AnyObject) {
fatalError()
}
}
これでアプリを実行して、上で追加したボタンを押して強制的にクラッシュさせれば良いのだが、いくつか注意点がある。
- ビルドしたときにデバッグする場合、Crashlyticsはクラッシュを拾えない。
Build Settingsからデバッグ情報の形式を変更する必要がある。
プロジェクトの[Build Settings] タブの[All]タブを選択して、検索窓から「debug information format」を検索し、[Debug Information Format] 設定を [DWARF with dSYM File] に設定する。
XcodeがWarningで警告してくれたはず。
- 上のコードで追加したボタンを押してアプリをクラッシュさせるのだが、このボタンをデバッガを使用せずに動作させる。
方法としては、
- Xcodeで一度[Run]を押してシミュレータまたは実機でアプリを立ち上げる。
- 次に[Stop]を押してアプリを停止させる。
- シミュレータまたはデバイスでアプリを開き、追加したボタンを押してクラッシュさせる。
- 再度アプリを開くとCrashlytics API によってクラッシュが報告される。
最初にRunしたときの初期インスタンスには、Crashlytics の動作を妨げるデバッガが含まれているらしい。
- Firebaseのコンソールに反映されるまで5分ほどかかる。
5分以上かかった気がしたが、少し気長に待てば反映される。
クラッシュレポートのカスタマイズ
公式ドキュメントを参考にして、より効果的にクラッシュレポートを利用したい。
カスタムキーの追加
Key-ValueのセットをCrashlyticsに設定することで、キーを使用してクラッシュレポートを検索、フィルターできる。
Crashlytics.crashlytics().setCustomValue(300, forKey: "int_key")
Crashlytics.crashlytics().setCustomValue("300", forKey: "str_key")
既存のキーの値を更新するには、以下のように同じキーを指定して値を設定するだけ
Crashlytics.crashlytics().setCustomValue(300, forKey: "int_key")
Crashlytics.crashlytics().setCustomValue("200", forKey: "int_key")
配列を使用して、一括で複数のKey-Valueペアを設定することもできる。
let keysAndValues = [
"str_key" : "string1",
"str_key2" : "string2",
"bool_key" : true,
"bool_key2" : false,
"float_key" : 1.41,
"float_key2" : 1.73
] as [String : Any]
Crashlytics.crashlytics().setCustomKeysAndValues(keysAndValues)
コンソールのイベントに集計されるので、上手く使用できればデバッグに役立ちそうなので、後々使用してみたい。 (イメージができないので、こんなケースで使えるよという使用例を知りたい。)
カスタムログ メッセージを追加
Crashlyticsログをアプリに追加することで、Crashlyticsでログを確認できる。
Crashlytics.crashlytics().log("button tapped!, \(className)")
getVaList() の呼び出しから返される値をフォーマットするログを出す場合は、
Crashlytics.crashlytics().log(format: "%@, %@", arguments: getValist["button tapped!", \(className)])
のようにも書ける。
これらのメソッドは、ユーザーからのアクションを受け取ったときや画面遷移、エラーが発生する可能性がある箇所に配置すると良さそう。
ユーザーIDの設定
どのユーザーがどのクラッシュを発生したかを特定できるように、メソッドが用意されている。
Crashlytics.crashlytics().setUserID("userId")
ログインしたタイミングでuserIdを設定すると良さそう。
致命的でない例外を報告する
致命的でないエラーを記録するにはrecordError()メソッドを使用する。
このとき、NSErrorオブジェクトが記録される。
Crashlytics.crashlytics().record(error: error)
NSErrorなので、通常のErrorとは異なるので扱いに注意する。
公式ドキュメントにはNSErrorを利用する際の注意点やパフォーマンスの問題に言及しているため、目を通すと良さそう。
dSYMファイルが不足していると表示された
コンソールで確認すると、dSYMファイルが不足していると表示されているので、ドキュメントに従い以下を試した。
試したこと
- BuildSettingsのDebug Information FormatをDWARF with dSYM fileに設定した。
- ビルドの最後にCrashlyticsが走るようにする
Run Scriptを確認したが、ちゃんと最後に書かれていた。 - 手動でdSYMファイルを見つけてアップロードする方法がドキュメントに示されているので、それに従った。
以下をターミナルで実行した。upload-symbolsとGoogleService-Info.plist 、dSYMsのpathはそれぞれ変更する必要がある。
dSYMファイルはXcodeのDerivedDataのプロダクトフォルダ内を探すと見つかった(デフォルトらしい)
/path/to/pods/directory/FirebaseCrashlytics/upload-symbols -gsp /path/to/GoogleService-Info.plist -p ios /path/to/dSYMs