モバイル向けセッションリプレイが一般公開!ユーザー体験を簡単に改善する方法を徹底解説

Article by: Jasmin Kassas, Sarah Guthals モバイル向けセッションリプレイがついに一般公開されました。 セッションリプレイの偉大さについて大袈裟に語ることもできますが、今回は趣向を変えて、A…I…があなたのために一句詠みます。 画面が固まる 開発者はため息 リプレイ明かす犯人は…… .addListener 忘れていた 俳句になっているかどうかはさておき、要するに Sentry はユーザーの操作を動画のように再現できるため、どのデバイスで問題が発生しているのか、他の端末を使って再現確認しなくても、不具合の箇所や体験が途切れているポイントをすぐに確認できます。 今どき iPhone 12 Mini が家に転がっている人なんてそうそういませんよね?少なくとも、私たちの手元にはありません。あなたのところはいかがですか? さて、本題に移ります。もし実際の問題をセッションリプレイでどのようにデバッグできるのか知りたい方は、この先をご覧ください。そうでない場合は、iOS、Android、Flutter、React Nativeのセットアップ方法をまとめたドキュメントをぜひご覧ください。 セッションリプレイでどう解決するのか 奇妙なバグの通知を受け取り、クラッシュダンプを見てもなぜユーザーがその状態に至ったのかわからなかった… 開発者であればそんな経験はよくあるでしょう。 その度に状態を把握するためランダムなログを無闇に差し込み、それを再リリースしてユーザーにアップデートを強制するも的が外れてまたやり直し… そんなことを繰り返していませんか? しかしセッションリプレイならそんな手間を省くことができます。エラーや操作の流れも含めて確認することができるため、ユーザーがエラーに至るまでに何をしていたのかが正確に確認できます。 ここからは、過去6ヶ月間のベータ期間に Sentry のお客様が実際に体験された事例をご紹介していきます。 モバイルアプリの状態を正確に把握する モバイルアプリは実にさまざまな形式があり、その多くは複雑なUIフローや状態を保持しています。セッションリプレイを使用することで、アプリがどのような状態なのかを正確に把握することができ、問題の原因になっているUIフローを見つけることができます。 以下の画像のように、バックエンドのエラーも含めて全体像を掴むのにとても役立ちました。 セッションリプレイがなければ、問題が起きた時の再現手順を特定するのに不要な手間がかかります。これは複雑な条件(手順や状態)をデバッグする際に特に役立ちます。 バックエンドのエンドポイントエラーにも対応 ユーザーがどのような操作をしていたか分からない状態で、サーバーのエラーをデバッグするのは本当に骨が折れます。 しかしセッションリプレイを使えば、エンドポイントに到達するまでのユーザー操作をそのまま見ることができます。またタイムラインビューを使うことでサーバーエラーが発生した正確なタイミングに一瞬でジャンプすることもできます。 とあるお客様の事例を挙げると、アプリがフォアグラウンドに戻った際にプロフィールを更新しようとして、400エラーが発生していたことがありました。 原因はその時点でユーザーがログアウトしていたからでした。修正はシンプルで、今では AppState イベントを監視しユーザーがログアウト状態ならすぐにログイン画面へリダイレクトするように修正しています。 モバイル特有の問題も見逃さない セッションリプレイのパンくずリストを使えば、ユーザーの操作履歴とともにデバイスに関する重要な情報も取得できます。どの瞬間に、どのような操作や理由によって問題が起きたのかを正確に特定します。 例えば「コードに問題はなかったのに、ネットワークが突然切れてオフラインになったこと」が原因だった(調査する開発者にとっては、これほど最悪なケースはありません)としても、セッションリプレイを見れば一目瞭然です。 このパンくずリストは、従来のログでは見えない部分に光を当ててくれる貴重な手掛かりになります。 モバイル向けセッションリプレイ導入手順 セッションリプレイをアプリに組み込むためのステップは以下の通りです。 […]
【モバイル開発】未来は宣言型にある

モバイル開発のエコシステムは常に非常に多様であると言えます。(デスクトップ)ウェブ開発のエコシステムよりも多様だと言えるでしょう。日々、ウェブ開発者向けのフレームワークやツールは増えているようですが、その多くはJavaScriptの上に構築されています。 その多くは、互いに似たようなパターンを実装しています。一方、モバイルのエコシステムには、コアとなる複数の言語セットがあり、そのためモバイル向けのツールやフレームワークの違いを識別するのは非常に簡単です。 モバイルのネイティブプラットフォームの代表格といえば、ネイティブのAndroidとiOSの2つがあります。 どちらも最近興味深いイノベーションがありました。近年Jetpack ComposeとSwiftUIの導入がありました。 ネイティブアプリの開発は、React NativeやFlutterアプリの開発と非常によく似ています。React NativeもFlutterも、最初から宣言型アプローチをとっています。 AndroidとiOSも現在、宣言型のアプローチを採用しています。 モバイル開発の未来は、宣言型であると言えるでしょう。 ちょっとした歴史 React NativeやFlutterは常に宣言型のアプローチをとってきましたが、AndroidとiOSは当初はそうではありませんでした AndroidはViewを活用していました(今もそうですが)。ViewはXMLファイルです。 Button、TextView、LinearLayoutなどのウィジェットを使ってユーザーインターフェイスを定義します。開発者はこれらのウィジェットにIDを割り当てます。これらのIDは、Javaファイルの中でウィジェットを参照するために使用されます。 ファイルでは、機能と動作を開発します。以下は、Viewファイルの例です: このようにウィジェットのリファレンスを作成することになります。 iOSには、Auto Layout、UIAppearance、Objective-Cの@property宣言、KVCコレクション演算子、Combineといった宣言型の機能がありました。 しかし、それでもある程度の命令型のコードを書く必要がありました。 例えば、iOSにはStoryboardsがありました(今もあります)。Storyboardsは、私たちがUIを構築するために使うグラフィカルなツールですが、実際にはXMLファイルです。しかし、開発者はXMLのコード自体にはほとんど触れません。ここでは、StoryboardsでUI要素を追加し、参照とアクションを作成する方法を紹介します。 宣言型に移行する 記憶を呼び覚ますと、命令型アプローチとは、目的のUIを実現するまでのステップバイステップの指示を出すことです。宣言的アプローチとは、最終的なUIがどのような状態になるかを記述することです。 Androidの新しいJetpack ComposeはKotlinで書かれています。 これはマークアップ言語であるXMLとは対照的なプログラミング言語です。 先ほどのXML Viewの例は、Jetpack Composeではこのようになります。 ご覧のように、このアプローチでUIを構築すると、必要なコードはかなり少なくなります。プログラミング言語を使えば、ウィジェットへの参照を作成し、そのウィジェットにロジックを取り付ける代わりに、変数とコールバックを直接使用することができます。値に変化があれば再構成(リレンダリング)が行われるため、UIは常に最新の状態に保たれます。 iOSのSwiftUIはほとんど同じで、Jetpack Composeの代わりにSwiftで構築されています。先ほどのStoryboardの例は、SwiftUIではこのようになります。 ここでもコード量がぐっと減ります。ここはプログラミング言語なので、Buttonのラベルを直接定義することができます。 参照を作成することなく、onClickコールバックを提供することができます。 命令型UIKitで作業しているときに、問題が見つかりました。ViewをView階層に追加する前に、Viewの制約を有効にする必要があります。 subview.leadingAnchor.constraint(…)の行とview.addSubview(view)の行を入れ替えるとエラーにならずに動作します。最初にこのエラーに遭遇したとき、何が起こっているのか理解するのに時間がかかりました。 理解しやすくなるまで、さらに何度かこのエラーを発生させてみました。しかし、新しい宣言的アプローチでは、この問題に遭遇することはないでしょう。 AndroidとiOSにおけるこの宣言型へのシフトは、より良い開発者体験とより速い開発への大きな一歩となります。プログラミング言語を使ってUIを宣言型で定義することで、AndroidやiOSの開発者が抱える多くの苦悩を解決することができます。 ここでは、宣言型アプローチの利点を紹介します。 テーマ設定が簡単になり、より動的になります。 ステートマネジメントは自然に感じられ、新しい宣言的アプローチにおいて重要な役割を果たします。 コンポジションアプローチでは、要素をネストすることでUIを構成することができます ダイナミックレイアウトや条件付きレンダリングが簡単にできるようになりました。 なぜでしょうか?それは制御構造や分岐ロジックを持つプログラミング言語を使ってUIを構築しているからです XMLを介するよりもSwift/Kotlinのコードを介した方がgrepがしやすくなります。 プログラミング言語の他の部分に適用されるのと同じツールを使って、より体系的にコードを再構築することができます。 PRのコード差の方がわかりやすくなります。 UI要素は、マークアップ言語とは対照的に、実際のデータ構造(関数、クラス、構造体)で構築されています。 そのため、Viewのユニットテストも行うことができます。 もちろん、気にかけるべき欠点は常にいくつか存在します。 SwiftUIとJetpack Composeはまだ生まれて数年しか経っていません。 ドキュメントの不足、コミュニティの小ささ、いくつかのパフォーマンスの問題(例えばAndroidの遅延カラム)などの欠点があり、また以前のフレームワークからのすべてのコンポーネントがサポートされているわけではありません。 より複雑なUIを構築しようとすると、制限があります。SwiftUIとJetpack Composeの両方は、まだ進化し、改善されています。 […]