Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Flutter研修【MIXI 25新卒技術研修】

Flutter研修【MIXI 25新卒技術研修】

本スライドは、MIXIの2025年度新卒向け技術研修で使用された資料です。
 
MIXI 2025新卒技術研修
『Flutter研修』

リポジトリ:https://github.com/mixigroup/2025BeginnerTrainingFlutter
 
───────────────────────────────
※皆様へのお願い※ 資料・動画・リポジトリのご利用について
───────────────────────────────
公開している資料や動画は、是非、勉強会や社内の研修などにご自由にお使いいただければと思いますが、以下のような場でのご利用はご遠慮ください。
- 受講者から参加費や授業料など金銭を集めるような場での利用
(会場費や飲食費など勉強会の運営に必要な実費を集める場合は問題ありません)
- 出典を削除または改変しての利用

Avatar for MIXI ENGINEERS

MIXI ENGINEERS PRO

April 24, 2025
Tweet

Video

More Decks by MIXI ENGINEERS

Other Decks in Technology

Transcript

  1. ©MIXI 2 • 2023新卒 • 開発本部たんぽぽ室たんぽぽグループ • mixi2 のエンジニア •

    ウイスキーが好きです 川瀬 寛也 • 2021新卒 • 開発本部たんぽぽ室たんぽぽグループ • mixi2 のアプリエンジニア • ワインが好きです 久野 文菜 講師/チューター 講師 チューター
  2. ©MIXI 4 研修の前に、以下をインストールしてください • mise ◦ 各ランタイムのバージョンを管理するツールです • Xcode 16.3

    ◦ ダウンロードにはApple IDが必要です ◦ xcodes を使ってインストールするのがおすすめです • Android Studio 2024.3 はじめに 事前準備 Getting Started | mise-en-place https://mise.jdx.dev/getting-started.html Resources - Xcode - Apple Developer https://developer.apple.com/xcode/resources/ XcodesOrg/xcodes: The best command-line tool to install and switch between multiple versions of Xcode. https://github.com/XcodesOrg/xcodes Download Android Studio & App Tools - Android Developers https://developer.android.com/studio
  3. ©MIXI 8 • やらないこと ◦ 基本文法の解説 ◦ 手順の写経 ▪ 各演習では参考となるコードを載せていますが、従わなくても良いです

    • やること ◦ 講義 + 演習 … 手を動かしながら学ぶ ◦ 小さくても運用を見据えた構成 はじめに この研修のポリシー
  4. ©MIXI 9 1. モバイルアプリ開発とFlutter 2. アプリアーキテクチャ 〜実装に入る前に〜 3. アプリを”ひとまず"作ってみる 4.

    今回作るアプリの概要 5. UI構築 6. 状態管理とDI 7. 非同期値の取り扱い 8. ルーティング 9. 送信処理 10. テスト はじめに 旅路 11. UI品質保証 12. Flutter以外の選択肢と技術選定力 13. まとめ・振り返り
  5. ©MIXI 11 • UI ◦ レイアウト、ナビゲーション、アニメーション、デザインシステム • 状態管理 ◦ ローカル状態、グローバル状態、非同期処理の整合性

    • 通信と同期 ◦ ネットワーク通信、データ同期、オフライン対応、キャッシュ戦略 • 認証とセキュリティ ◦ ユーザー認証、データ保護 • 品質保証 ◦ テスト、デバッグ、モニタリング • 運用と配信 ◦ CI/CD、バージョン管理、ストア配信 etc… モバイルアプリ開発とFlutter モバイルアプリ開発で考えること
  6. ©MIXI 12 • 代表技術 ◦ Swift + SwiftUI / Kotlin

    + Jetpack Compose • 特徴 ◦ OSに最適化された公式スタック ◦ 最良のパフォーマンスとユーザー体験 ネイティブ • 代表技術 ◦ (後述) • 特徴 ◦ 単一コードベースで複数プラットフォーム 対応 ◦ 保守性と再利用性のバランス クロスプラットフォーム モバイルアプリ開発とFlutter 開発アプローチの種類 SwiftUI | Apple Developer Documentation https://developer.apple.com/documentation/swiftui Jetpack Compose UI App Development Toolkit - Android Developers https://developer.android.com/compose
  7. ©MIXI 13 • WebView ◦ 代表技術: TypeScript + Capacitor /

    Rust + Tauri ◦ 特徴: Web資産流用に最適 • ネイティブUI ◦ 代表技術: TypeScript + React Native / Kotlin + Compose Multiplatform / Swift + Skip ◦ 特徴: ネイティブに近い体験 • 独自レンダリング ◦ 代表技術: Dart + Flutter / C# + Unity ◦ 特徴: 高いカスタマイズ性 モバイルアプリ開発とFlutter クロスプラットフォームの分類 Capacitor by Ionic - Cross-platform apps with web technology https://capacitorjs.com/ Tauri 2.0 | Tauri https://tauri.app/ React Native · Learn once, write anywhere https://reactnative.dev/ Compose Multiplatform UI Framework | JetBrains https://www.jetbrains.com/compose-multiplatform/ Skip | Dual-platform app development in Swift https://skip.tools/ Unity Real-Time Development Platform | 3D, 2D, VR & AR Engine https://unity.com/
  8. ©MIXI 14 • Googleが開発・保守するクロスプラットフォームUIフレームワーク ◦ 2014年に Sky として開発開始、2018年にFlutter 1.0リリース •

    単一コードベースで iOS / Android™ / Web / Windows / macOS / Linux / (Fuchsia) に対応 • 世界中で 100万人以上 の月間アクティブ開発者 • 新規iOSアプリの 約30% がFlutterで構築されている(2024年) モバイルアプリ開発とFlutter Flutterとは? Flutter-on-Fuchsia Velocity https://fuchsia.dev/fuchsia-src/contribute/roadmap/2021/flutter_on_fuchsia_velocity Celebrating Flutter’s “Production Era” | by Michael Thomsen | Flutter | Medium https://medium.com/flutter/flutter-in-production-f9418261d8e1 ※「Android」は、Google LLC の商標または登録商標です。
  9. ©MIXI 15 モバイルアプリ開発とFlutter Flutterアーキテクチャ概要 明確に分離された3層構造 → 高いパフォーマンスと柔軟なUI構築を実現 Flutter architectural overview

    | Flutter https://docs.flutter.dev/resources/architectural-overview アプリ開発者が主に触れる層 (Dart) Widget, Rendering, Animationなど ランタイムのコア (C++) ImpellerまたはSkiaによる描画、Text Rendering、Dart Runtime 各プラットフォーム固有 OSのエントリーポイント
  10. ©MIXI 17 • アーキテクチャとは ◦ アプリケーションを構成する技術・構造・方針の集合 ◦ 構成要素の責務と関係性を定義する枠組み • なぜ存在するのか

    ◦ 開発の初期段階から運用・保守まで破綻しない構造を提供するため ◦ 拡張性・テスト容易性・保守性を確保するため • なぜ学ぶ必要があるのか ◦ 運用に耐えるアプリを設計・評価するため アプリアーキテクチャ アーキテクチャとは何か、なぜ必要か? 動くアプリではなく「運用できるアプリ」を作るために不可欠
  11. ©MIXI 18 • Separation of Concerns(関心の分離) ◦ 機能ごとに自己完結したユニットに分離 ◦ UIロジックとビジネスロジックを明確に分ける

    ◦ ウィジェットは再利用可能かつロジックを最小限に保つ • Layered Architecture(レイヤードアーキテクチャ) ◦ アプリケーションを3層(UI層, ロジック層, データ層)に分離 ◦ 各層は隣接する層としか通信しない アプリアーキテクチャ 基本原則 Architecture concepts | Flutter https://docs.flutter.dev/app-architecture/concepts
  12. ©MIXI 19 • Single Source of Truth(SSOT, 信頼できる唯一の情報源) ◦ 各データ型は唯一の責務を持つクラスで管理

    ◦ 同じデータを複数箇所で保持しない。バグを抑制 • Unidirectional Data Flow(単方向データフロー) ◦ ユーザー操作は UI → ロジック → データ の順にイベントとして処理される ◦ 逆に状態は データ → ロジック → UI の順に流れる ◦ 状態の更新は常にデータ層(SSOT)を通じて行う アプリアーキテクチャ データの流れ Architecture concepts | Flutter https://docs.flutter.dev/app-architecture/concepts
  13. ©MIXI 20 • Co-location (コロケーション) ◦ 関連するリソースをまとまりで管理する ◦ 機能をディレクトリ単位で並置して認知負荷を下げる •

    Screaming Architecture(叫ぶアーキテクチャ) ◦ ディレクトリ構成等から「何をするか」が即座に伝わる状態 ◦ コロケーション文脈では、機能ベースのフォルダ名 アプリアーキテクチャ 関心の分離を保ちつつ機能単位でまとめる レイヤーは論理構造、コロケーションは物理配置 Colocation https://kentcdodds.com/blog/colocation Clean Coder Blog https://blog.cleancoder.com/uncle-bob/2011/09/30/Screaming-Architecture.html
  14. ©MIXI 23 • 1. 好きな名前でFlutterプロジェクトを作ってみよう ◦ 英小文字、数字、アンダースコアが使えます 2. 起動してみよう ◦

    iOSでもAndroidでもWebでも 実機・エミュレータのどちらでも大丈夫です アプリを”ひとまず”作ってみる はじめの一歩 ハイフンは使え ないことに注意 演習
  15. ©MIXI 24 1. DartPad https://dartpad.dev/ にアクセス 2. 「Flutter Snippet」から自然言語で作りたいアプリを説明 ◦

    プレビューで確認しながら、気に入るまで「Update code」 3. lib/main.dart にコピー&ペースト ◦ 必要ならパッケージのインストール (例: 4. (flutter runを実行したterminal上で)r キーを押して Hot reload 、 R キーを押して Hot restart アプリを”ひとまず”作ってみる Let’s Vibe Coding! 演習 DartPad https://dartpad.dev/
  16. ©MIXI 26 • 主な機能 ◦ 投稿一覧機能 ◦ 投稿作成機能 ◦ 投稿データはサーバーとリアルタイム同期

    • 画面構成 ◦ / … ホーム画面(タイムライン) ◦ /compose … 投稿作成画面 今回作るアプリの概要 簡易SNSクライアントを作ろう
  17. ©MIXI 27 • Nostrというプロトコルを利用 (Note and Other Stuff Transmitted by

    Relays) ◦ WebSocketで接続できる分散型ソーシャルネットワークプロトコル ▪ WebSocket … 双方向リアルタイム通信を維持するための常時接続プロトコル ◦ 投稿を含むあらゆるものをイベントとして、リレーによって送信する • なぜ使うのか? ◦ 自前でプロトコルを定義しなくてよい ◦ 既存のリレーサーバーに繋ぐだけで”利用者の多いSNSアプリ”になる 今回作るアプリの概要 補足: 利用するSNSプロトコル nostr-protocol/nostr https://github.com/nostr-protocol/nostr
  18. ©MIXI 29 • StatelessWidget ◦ 状態を持たないウィジェットの基本クラス 1. lib/ 下に pages/timeline/page.dart

    を作成して、 TimelinePage を作ってみよう 2. lib/main.dart から呼び出してみよう UI構築 タイムラインのベースを作ろう 演習 StatelessWidget class - widgets library - Dart API https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html
  19. ©MIXI 30 • StatelessWidget ◦ 状態を持たないウィジェットの基本クラス 1. lib/ 下に pages/timeline/page.dart

    を作成して、 TimelinePage を作ってみよう 2. lib/main.dart から呼び出してみよう UI構築 タイムラインのベースを作ろう 演習 StatelessWidget class - widgets library - Dart API https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html
  20. ©MIXI 31 • Everything is a Widget ◦ 視覚要素(ボタン、テキスト)だけでなく、レイアウトや振る舞いなど全てがウィジェット ◦

    コンポジション(合成)によって複雑なUIをシンプルに組み立てる • 宣言的UI ◦ UI = f(state) の純粋関数的なモデルに基づく ◦ 状態が変化すれば、該当するウィジェットツリーを再構築する ◦ 明示的にUI更新ロジックを書く必要はない ◦ 再描画は差分検知で最適化される UI構築 FlutterのUI設計思想 「全てがウィジェットである」 Layout | Flutter https://docs.flutter.dev/ui/layout Inside Flutter | Flutter https://docs.flutter.dev/resources/inside-flutter
  21. ©MIXI 32 • FlutterはネイティブUIをラップしない。React Native等との差別点 • Skia ◦ 長年利用されてきたクロスプラットフォーム2D描画エンジン ◦

    CPU/GPU混在の柔軟なパイプライン ◦ パフォーマンスや安定性の面で限界があった • Impeller ◦ Flutter独自開発の新しい描画エンジン ◦ Vulkan/MetalなどのモダングラフィックスAPIを積極的に活用 ◦ シェーダーの事前コンパイルで描画の一貫性とフレーム飛びを抑制 UI構築 2つの描画アーキテクチャ Flutter 3.27以降、iOS/AndroidでImpellerがデフォルトに Impeller Availability https://docs.google.com/spreadsheets/d/1AebMvprRkxP-D6ndx920lbvDBbhg-sNNRJ64XY2P2t0/edit?gid=0#gid=0
  22. ©MIXI 33 • Material 3 ◦ Googleのデザインシステムで、Flutter標準採用 1. lib/pages/timeline/ 下に

    components/post_card.dart を作成して、 PostCard を作ってみよう • Material 3 の Card と ListTile などが利用できそう! 2. page.dart で PostCard を使ってみよう UI構築 投稿カードを作ろう Material Design 3 - Google's latest open source design system https://m3.material.io/ Card class - material library - Dart API https://api.flutter.dev/flutter/material/Card-class.html ListTile class - material library - Dart API https://api.flutter.dev/flutter/material/ListTile-class.html 演習
  23. ©MIXI 34 • Material 3 ◦ Googleのデザインシステムで、Flutter標準採用 1. lib/pages/timeline/ 下に

    components/post_card.dart を作成して、 PostCard を作ってみよう • Material 3 の Card と ListTile などが利用できそう! 2. page.dart で PostCard を使ってみよう UI構築 投稿カードを作ろう Material Design 3 - Google's latest open source design system https://m3.material.io/ Card class - material library - Dart API https://api.flutter.dev/flutter/material/Card-class.html ListTile class - material library - Dart API https://api.flutter.dev/flutter/material/ListTile-class.html 演習
  24. ©MIXI 35 1. lib/ 下に themes/colors.dart を作成して、 アプリ全体のカラーテーマを作ってみよう 2. lib/main.dart

    の ThemeData に設定しよう 3. 余裕があれば themes/fonts.dart に アプリ全体のテキストスタイルを作ってみよう UI構築 アプリテーマを設定しよう 演習
  25. ©MIXI 36 1. lib/ 下に themes/colors.dart を作成して、 アプリ全体のカラーテーマを作ってみよう 2. lib/main.dart

    の ThemeData に設定しよう 3. 余裕があれば themes/fonts.dart に アプリ全体のテキストスタイルを作ってみよう UI構築 アプリテーマを設定しよう 演習
  26. ©MIXI 37 • デザインシステムとは ◦ UIに一貫性と再利用性を与える設計のルール ◦ デザイナーと共通の”言語”を持つために不可欠 • Material

    3 の拡張性 ◦ UI構築に必要な要素が体系的に提供されている ◦ これをベースに、自分でデザインシステムを作っていける • Flutterのデザインシステム ◦ UIの一貫性を保ちつつ、メンテナンス性を向上できる ◦ ThemeData を活用して色や文字のテーマを一元管理 UI構築 デザインシステム クロスプラットフォームで統一感のあるUIを実現 Material | Flutter https://docs.flutter.dev/ui/widgets/material
  27. ©MIXI 39 • StatefulWidget ( + setState ) ◦ 状態を持つウィジェットの基本クラス

    1. TimelinePage に FloatingActionButton を 設置しよう 2. ボタンを押すと投稿がタイムラインに追加される ようにしてみよう 状態管理とDI タイムラインに投稿を追加しよう StatefulWidget class - widgets library - Dart API https://api.flutter.dev/flutter/widgets/StatefulWidget-class.html FloatingActionButton class - material library - Dart API https://api.flutter.dev/flutter/material/FloatingActionButton-class.html 演習
  28. ©MIXI 40 • StatefulWidget ◦ 状態を持つウィジェットの基本クラス 1. TimelinePage に FloatingActionButton

    を 設置しよう 2. ボタンを押すと投稿がタイムラインに追加される ようにしてみよう 状態管理とDI タイムラインに投稿を追加しよう StatefulWidget class - widgets library - Dart API https://api.flutter.dev/flutter/widgets/StatefulWidget-class.html 演習 押すと投稿が 追加される
  29. ©MIXI 42 • Single Source of Truth(SSOT, 信頼できる唯一の情報源) ◦ 各データ型は唯一の責務を持つクラスで管理

    ◦ 同じデータを複数箇所で保持しない。バグを抑制 • Unidirectional Data Flow(単方向データフロー) ◦ ユーザー操作は UI → ロジック → データ の順にイベントとして処理される ◦ 逆に状態は データ → ロジック → UI の順に流れる ◦ 状態の更新は常にデータ層(SSOT)を通じて行う [再掲] アプリアーキテクチャ [再掲] データの流れ Architecture concepts | Flutter https://docs.flutter.dev/app-architecture/concepts
  30. ©MIXI 43 • Ephemeral State(ローカル状態) ◦ 単一ウィジェット内で完結するもの ◦ UIの一時的な状態。アニメーション進行度など •

    App State(グローバル状態) ◦ アプリ全体で共有されるもの ◦ ページ間で情報は共有されるべきであるため、モバイルアプリはApp Stateが多い 状態管理とDI 2つの「状態」 Differentiate between ephemeral state and app state | Flutter https://docs.flutter.dev/data-and-backend/state-mgmt/ephemeral-vs-app
  31. ©MIXI 44 • 状態が複数のウィジェットにまたがると管理が難しい ◦ 親から子ウィジェットへの伝播が煩雑 • 状態がウィジェットに埋め込まれると再利用が難しい ◦ ロジックとUIが密結合し、可読性も低下

    • アプリケーション全体の状態を一元管理できない ◦ グローバルに共有すべき状態に対応不可 状態管理とDI setStateの限界 setStateはローカルには有効だが、アプリ全体の設計には不十分
  32. ©MIXI 45 • 状態管理ライブラリは複数あるが、特に日本語圏ではRiverpodが代表的 • なぜ Riverpodを利用するのか ◦ 状態とUIを分離できる ◦

    UIとロジックのテスト性を向上できる ◦ 非同期や複数画面でも簡単に状態管理できる • Riverpodの仕組み ◦ 状態をプロバイダー経由で注入 ◦ UIは必要な状態だけを監視すれば良い 状態管理とDI グローバル状態の管理とRiverpod Riverpod https://riverpod.dev/
  33. ©MIXI 46 1. flutter_riverpod を依存関係に追加する 2. ProviderScope を main.dart に追加する

    ◦ スコープ単位で状態の分離ができる ◦ 今回はアプリのエントリーポイントに配置 状態管理とDI Riverpodで書き換えよう 演習 Riverpod https://riverpod.dev/
  34. ©MIXI 47 3. lib/pages/timeline/ 下に provider.dart を作成して、 timelineProvider を作ろう 4.

    TimelinePage を書き換えよう 状態管理とDI Riverpodで書き換えよう 演習 Notifier class - riverpod library - Dart API https://pub.dev/documentation/riverpod/latest/riverpod/Notifier-class.html
  35. ©MIXI 48 3. lib/pages/timeline/ 下に provider.dart を作成して、 timelineProvider を作ろう 4.

    TimelinePage を書き換えよう 状態管理とDI Riverpodで書き換えよう 演習 挙動に変化が なければOK Notifier class - riverpod library - Dart API https://pub.dev/documentation/riverpod/latest/riverpod/Notifier-class.html
  36. ©MIXI 49 • DIとは? ◦ 依存関係(= 他のオブジェクトやリソース)を外部から提供する設計手法 ◦ オブジェクトが自ら依存対象を生成せず、外部から受け取る ◦

    保守性・テスト容易性・再利用性の向上につながる • RiverpodとDIの関係 ◦ プロバイダーがDIのユニットになっている ◦ 依存オブジェクトを定義し、必要な場所で注入する設計 状態管理とDI DI (Dependency Injection) 構造を明示的にし、アプリの保守性を支える Providers | Riverpod https://riverpod.dev/docs/concepts/providers#why-use-providers
  37. ©MIXI 53 • 非同期状態管理のためのNotifier派生型 • 状態は AsyncValue<T> で管理され、ローディングやエラーを明示的に扱える • AsyncNotifier

    ◦ 一過性の非同期処理に最適(初回ロード、操作後の更新など) ◦ 呼び出しごとに処理が完結し、開始を明示的に制御できる • StreamNotifier ◦ 継続的な状態変化を扱う(WebSocketの購読など) ◦ ストリームに流れるデータをリアクティブに処理したい場合に適する 非同期値の取り扱い AsyncNotifier / StreamNotifier 一過性の非同期処理にはAsyncNotifier, 継続的な変化にはStreamNotifier AsyncNotifier class - riverpod library - Dart API https://pub.dev/documentation/riverpod/latest/riverpod/AsyncNotifier-class.html StreamNotifier class - riverpod library - Dart API https://pub.dev/documentation/riverpod/latest/riverpod/StreamNotifier-class.html
  38. ©MIXI 54 1. web_socket_channel を依存関係に追加 ◦ 標準の dart:io を使っても良いが、 クロスプラットフォーム対応したい

    2. StreamNotifier で timelineProvider を 書き換えてみよう • 研修のために用意したリレーサーバーのURLは Slackに貼ります 非同期値の取り扱い 投稿データを取得しよう web_socket_channel | Dart package https://pub.dev/packages/web_socket_channel WebSocket class - dart:io library - Dart API https://api.dart.dev/dart-io/WebSocket-class.html StreamNotifier class - riverpod library - Dart API https://pub.dev/documentation/riverpod/latest/riverpod/StreamNotifier-class.html 演習
  39. ©MIXI 55 3. ウィジェットに反映しよう • 研修リポジトリの server/ を見て、ローカルに リレーサーバーを立ててもOK •

    動作に問題がなければ実世界のリレーサーバーに 接続しても勿論OK 非同期値の取り扱い 投稿データを取得しよう AsyncValue class - riverpod library - Dart API https://pub.dev/documentation/riverpod/latest/riverpod/AsyncValue-class.html 演習 型が変わる ことに注意
  40. ©MIXI 56 3. ウィジェットに反映しよう • 研修リポジトリの server/ を見て、ローカルに リレーサーバーを立ててもOK •

    動作に問題がなければ実世界のリレーサーバーに 接続しても勿論OK 非同期値の取り扱い 投稿データを取得しよう AsyncValue class - riverpod library - Dart API https://pub.dev/documentation/riverpod/latest/riverpod/AsyncValue-class.html 演習 型が変わる ことに注意 タイムラインは 自動で更新される
  41. ©MIXI 58 • ConsumerStatefulWidget ◦ ConsumerWidget + StatefulWidget • 投稿作成画面を作ってみよう

    • 投稿送信処理は今は空でOK ◦ 非同期処理を行う予定なので AsyncNotifier ルーティング 投稿作成画面を作ろう 演習
  42. ©MIXI 59 • ConsumerStatefulWidget ◦ ConsumerWidget + StatefulWidget • 投稿作成画面を作ってみよう

    • 投稿送信処理は今は空でOK ◦ 非同期処理を行う予定なので AsyncNotifier ルーティング 投稿作成画面を作ろう 演習 送信ボタンを押しても 内容が消えない =状態が保持されている
  43. ©MIXI 60 • 画面遷移の定義と制御を行う仕組み • 2つのアプローチが存在する ◦ Navigator … 命令的ルーティング

    ▪ push() / pop() を用いて遷移する ◦ Router … 宣言的ルーティング ▪ URLベースの定義。Web対応するならほぼ必須 ▪ go_router などライブラリを利用することが推奨されている • パラメーター・クエリ・遷移アニメーション対応 ルーティング ルーティングとは? Navigation and routing | Flutter https://docs.flutter.dev/ui/navigation
  44. ©MIXI 61 1. go_router を依存関係に追加 2. lib/ 下に router.dart を追加し、

    router を定義 3. main.dart で router を設定 4. 各ページで遷移先を指定 ◦ context.push() / context.pop() が使えます ルーティング go_router で画面遷移 演習
  45. ©MIXI 62 1. go_router を依存関係に追加 2. lib/ 下に router.dart を追加し、

    router を定義 3. main.dart で router を設定 4. 各ページで遷移先を指定 ◦ context.push() / context.pop() を使います ルーティング go_router で画面遷移 演習
  46. ©MIXI 64 • 投稿データ = JSONイベント • 秘密鍵で署名する ◦ bip340

    … Schnorr署名に準拠したライブラリ • 秘密鍵を保存する(=ユーザー作成機能をつける)なら ◦ flutter_secure_storage … セキュアにローカルにデータを保存するライブラリ 送信処理 Nostrの投稿には署名が必要 bip340 | Dart package https://pub.dev/packages/bip340 flutter_secure_storage | Flutter package https://pub.dev/packages/flutter_secure_storage
  47. ©MIXI 68 • テストしやすい設計とは? ◦ 状態とUIの責務が分かれている ◦ ロジックがウィジェットから独立している ◦ DIにより依存対象を差し替えられる

    テスト アーキテクチャとテストの関係性 今まで作ってきた構造は、すでに「テストしやすい」状態にある
  48. ©MIXI 69 • 単体テスト ◦ 小さな単位のロジックを検証 ◦ ランタイムが高速 ◦ アプリの核となるロジックを高速かつ確実に保証する

    • ウィジェットテスト ◦ Widgetの表示内容や操作に対する動作を検証 ◦ 中程度の速度 ◦ UIが意図通りか、操作に応答するかを局所的に確認する テスト Flutterにおけるテストの種類 (1)
  49. ©MIXI 70 • ゴールデンテスト ◦ 見た目が意図通りかを画像として検証 ◦ 基準画像(ゴールデンファイル)とのピクセル差分比較 ◦ デザインの不整合をCIで早期に検出する

    • 統合テスト ◦ アプリ全体の動作を検証 ◦ ユーザーが実際に操作する流れをシミュレートする ◦ ネットワーク通信や画面遷移の一貫性を保証する テスト Flutterにおけるテストの種類 (2)
  50. ©MIXI 71 1. タイムラインから投稿画面への画面遷移のテストを書いてみよう 2. 余裕があるなら投稿作成のテストを書いてみよう ◦ ProviderScope(overrides: ) が利用できます

    テスト ウィジェットテストを書いてみよう 演習 ProviderScope class - flutter_riverpod library - Dart API https://pub.dev/documentation/flutter_riverpod/latest/flutter_riverpod/ProviderScope-class.html
  51. ©MIXI 72 • PostCard のテストを書いてみよう • alchemist https://pub.dev/packages/alchemist を利用するのが簡単です テスト

    ゴールデンテストを書いてみよう Betterment/alchemist: A Flutter tool that makes golden testing easy. https://github.com/Betterment/alchemist 演習
  52. ©MIXI 73 • 現実的な課題 ◦ テストは書いて終わりではなくメンテナンスする必要がある ◦ UI変更に追従できないテストはすぐ”腐る” ◦ (特にフロントエンドにおいて)TDDが必ずしも生産性を上げるとは限らない

    • 現実的な運用 ◦ 価値の高い箇所に重点的に適用する。認証機能など ◦ カバレッジよりも、変更に強い構造を優先する テスト テストは銀の弾丸ではない
  53. ©MIXI 74 • 自動化による品質維持 ◦ テストはCIでの検証を前提にする ◦ PR単位でのフィードバックで修正コストを抑える ◦ 本番環境を見据えたビルド検証や段階的リリース

    • テストで補えない領域への対応 ◦ テストが補足できない問題(パフォーマンス、設定ミスなど)も多い ◦ メトリクス・ログ・トレースを使った継続的なシステム監視 テスト CI/CD・監視 テストだけに依存しない設計と運用の仕組みが品質を支える
  54. ©MIXI 76 • ゴールデンテストの課題 ◦ UIの見た目を画像で保証 → 画面変更に脆弱 ◦ 画像差分が生じるとfalse

    positive(偽陽性)が頻発 ◦ 実際に「目で確認したい」だけのケースも多い • UIカタログがその代替になり得る ◦ FlutterだとWidgetbookが代表的 UI品質保証 ゴールデンテストの限界と代替案 Widgetbook - Review all UI changes of your Flutter app in seconds https://www.widgetbook.io
  55. ©MIXI 77 • Flutter製のUIカタログツール • 各コンポーネントの「状態違い」を一覧で表示できる • Webで言うStorybookのような、開発者(+ デザイナー)向けツール •

    UIパーツの集約場所として活用できる UI品質保証 Widgetbookとは? Widgetbook - Review all UI changes of your Flutter app in seconds https://www.widgetbook.io Storybook: Frontend workshop for UI development https://storybook.js.org/
  56. ©MIXI 79 • UIテスト・レビューの実務構成 ◦ デザインシステムの運用 ◦ ゴールデンテスト + UIカタログ

    + QA • UIが壊れてないことだけでなく、 「意図通りに表示されているか」を確認したいならUIカタログが有効 UI品質保証 実務での適用戦略
  57. ©MIXI 81 • 最初に問うべきこと ◦ そもそもアプリを作るべきなのか? ◦ ユーザーはどのような体験を求めているのか? ◦ 何に対して一番コストをかけるべきか?

    • 技術(フレームワーク)は目的を達成するための手段に過ぎない Flutter以外の選択肢と技術選定力 技術選定でまず考えるべきこと
  58. ©MIXI 84 • Flutterを選ぶなら ◦ 目的が「スピード」「複数OS対応」「UIの統一性」である ◦ Dart/Flutterの設計思想に共感できる • Flutterに固執しない

    ◦ ネイティブを選択しない損失を理解する ◦ 他のクロスプラットフォームフレームワークも正解になり得る ▪ 例: すでにWebアプリがありバックエンドがNode.jsで書かれている → React Nativeが有力候補 Flutter以外の選択肢と技術選定力 Flutterを選ぶときの判断軸 技術選定の前に、事業の前提を見直す
  59. ©MIXI 85 • 技術選定の本質は前提と制約の理解 ◦ 誰のために、どんな価値を提供したいのか? ◦ 何を優先して、どこを妥協するか? ◦ 運用体制(人・時間・資金)は現実に即しているか?

    • Flutterは強力なツールだが、万能ではない • 技術から始めない、目的から始める Flutter以外の選択肢と技術選定力 まとめ 「何を作るか」「どう運用するか」
  60. ©MIXI 88 • UI構築 ◦ 宣言的UI、デザインシステムとコロケーション • 状態管理 ◦ ローカル状態とグローバル状態

    ◦ ネットワーク通信、非同期処理 • テスト ◦ 4つのテスト手法、現実的な適用法 • 技術選定 ◦ 目的から技術を選ぶ視点 まとめ・振り返り この研修で得たもの
  61. ©MIXI 89 • プロトタイピング ◦ Flutterならあらゆるプラットフォームで即座に動く画面が作れる • 設計・レビュー ◦ アーキテクチャ、状態とUIの責務分離をレビューできる

    • 技術選定 ◦ 「Flutterにする?しない?」を根拠をもって議論できる まとめ・振り返り 実際の現場でどう応用するか?
  62. ©MIXI 90 • 今日作ったアプリは… ◦ WebSocketで実際のソーシャルネットワーク (Nostr) と接続している ◦ 任意のリレーサーバーにアクセスすれば、リアルタイムに人の投稿が見える

    ◦ UIや機能を拡張すれば、公開可能なSNSクライアントになる • あとは: ◦ いいね、リアクション、フォロー機能、プロフィール編集、ダイレクトメッセージ.... おまけ 「ぼくのかんがえたさいきょうのSNS」を作ろう