Share
Embed
Flutter研修【MIXI 26新卒技術研修】
本スライドは、MIXIの2026年度新卒向け技術研修で使用された資料です。
MIXI 2026新卒技術研修
『Flutter研修』
───────────────────────────────
※皆様へのお願い※ 資料・動画・リポジトリのご利用について
───────────────────────────────
公開している資料や動画は、是非、勉強会や社内の研修などにご自由にお使いいただければと思いますが、以下のような場でのご利用はご遠慮ください。
- 受講者から参加費や授業料など金銭を集めるような場での利用
(会場費や飲食費など勉強会の運営に必要な実費を集める場合は問題ありません)
- 出典を削除または改変しての利用
MIXI ENGINEERS PRO
July 22, 2026
Transcript
90 slides
-
はじめに 事前準備 研修の前に、以下をインストールしてください • mise ◦ • • ©MIXI 各ランタイムのバージョンを管理するツールです
Xcode 26.3 ◦ ダウンロードにはApple IDが必要です ◦ xcodes を使ってインストールするのがおすすめです ◦ Xcode 26.3 は macOS Sequoia 15.6 以降で利用できます Android Studio Panda 4 | 2025.3.4 Patch 1 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 各演習では参考となるコードを載せていますが、従わなくても良いです やること ◦ 講義 + 演習 … 手を動かしながら学ぶ ◦ 小さくても運用を見据えた構成 7 -
はじめに 旅路 1. モバイルアプリ開発とFlutter 11. UI品質保証 2. アプリアーキテクチャ 〜実装に入る前に〜 12.
Flutter以外の選択肢と技術選定力 3. アプリを”ひとまず"作ってみる 13. まとめ・振り返り 4. 今回作るアプリの概要 5. UI構築 6. 状態管理とDI 7. 非同期値の取り扱い 8. ルーティング 9. 送信処理 10. テスト ©MIXI 8 -
モバイルアプリ開発とFlutter モバイルアプリ開発で考えること • UI ◦ • 状態管理 ◦ • ユーザー認証、データ保護
品質保証 ◦ • ネットワーク通信、データ同期、オフライン対応、キャッシュ戦略 認証とセキュリティ ◦ • ローカル状態、グローバル状態、非同期処理の整合性 通信と同期 ◦ • レイアウト、ナビゲーション、アニメーション、デザインシステム テスト、デバッグ、モニタリング 運用と配信 ◦ CI/CD、バージョン管理、ストア配信 etc… ©MIXI 10 -
モバイルアプリ開発とFlutter 開発アプローチの種類 ネイティブ • 代表技術 ◦ • クロスプラットフォーム • Swift
+ SwiftUI / Kotlin + Jetpack Compose 特徴 ◦ • ◦ OSに最適化された公式スタック ◦ 最良のパフォーマンスとユーザー体験 代表技術 特徴 ◦ SwiftUI | Apple Developer Documentation https://developer.apple.com/documentation/swiftui Jetpack Compose UI App Development Toolkit - Android Developers https://developer.android.com/compose 単一コードベースで複数プラットフォーム 対応 ◦ ©MIXI (後述) 保守性と再利用性のバランス 11 -
モバイルアプリ開発とFlutter クロスプラットフォームの分類 • • • ©MIXI WebView ◦ 代表技術: TypeScript
+ Capacitor / Rust + Tauri ◦ 特徴: Web資産流用に最適 ネイティブUI ◦ 代表技術: TypeScript + React Native / Kotlin + Compose Multiplatform / Swift + Skip ◦ 特徴: ネイティブに近い体験 独自レンダリング ◦ 代表技術: Dart + Flutter / C# + Unity ◦ 特徴: 高いカスタマイズ性 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/ 12 -
モバイルアプリ開発とFlutter Flutterとは? • Googleが開発・保守するクロスプラットフォームUIフレームワーク ◦ 2014年に Sky として開発開始、2018年にFlutter 1.0リリース •
単一コードベースで iOS / Android™ / Web / Windows / macOS / Linux / (Fuchsia) に対応 • 公開されている直近の公式発信では、世界中で 100万人以上 の月間アクティブ開発者 • 同じく2024年時点で、新規iOSアプリの 約30% がFlutterで構築されている ©MIXI 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 の商標または登録商標です。 13 -
モバイルアプリ開発とFlutter Flutterアーキテクチャ概要 アプリ開発者が主に触れる層 (Dart) Widget, Rendering, Animationなど ランタイムのコア (C++) ImpellerまたはSkiaによる描画、Text
Rendering、Dart Runtime 各プラットフォーム固有 OSのエントリーポイント 明確に分離された3層構造 → 高いパフォーマンスと柔軟なUI構築を実現 ©MIXI Flutter architectural overview | Flutter https://docs.flutter.dev/resources/architectural-overview 14 -
アプリアーキテクチャ アーキテクチャとは何か、なぜ必要か? • • • アーキテクチャとは ◦ アプリケーションを構成する技術・構造・方針の集合 ◦ 構成要素の責務と関係性を定義する枠組み
なぜ存在するのか ◦ 開発の初期段階から運用・保守まで破綻しない構造を提供するため ◦ 拡張性・テスト容易性・保守性を確保するため なぜ学ぶ必要があるのか ◦ 運用に耐えるアプリを設計・評価するため 動くアプリではなく「運用できるアプリ」を作るために不可欠 ©MIXI 16 -
アプリアーキテクチャ 基本原則 • • ©MIXI Separation of Concerns(関心の分離) ◦ 機能ごとに自己完結したユニットに分離
◦ UIロジックとビジネスロジックを明確に分ける ◦ ウィジェットは再利用可能かつロジックを最小限に保つ Layered Architecture(レイヤードアーキテクチャ) ◦ アプリケーションを3層(UI層, ロジック層, データ層)に分離 ◦ 各層は隣接する層としか通信しない Architecture concepts | Flutter https://docs.flutter.dev/app-architecture/concepts 17 -
アプリアーキテクチャ データの流れ • • ©MIXI Single Source of Truth(SSOT, 信頼できる唯一の情報源)
◦ 各データ型は唯一の責務を持つクラスで管理 ◦ 同じデータを複数箇所で保持しない。バグを抑制 Unidirectional Data Flow(単方向データフロー) ◦ ユーザー操作は UI → ロジック → データ の順にイベントとして処理される ◦ 逆に状態は データ → ロジック → UI の順に流れる ◦ 状態の更新は常にデータ層(SSOT)を通じて行う Architecture concepts | Flutter https://docs.flutter.dev/app-architecture/concepts 18 -
アプリアーキテクチャ 関心の分離を保ちつつ機能単位でまとめる • • Co-location (コロケーション) ◦ 関連するリソースをまとまりで管理する ◦ 機能をディレクトリ単位で並置して認知負荷を下げる
Screaming Architecture(叫ぶアーキテクチャ) ◦ ディレクトリ構成等から「何をするか」が即座に伝わる状態 ◦ コロケーション文脈では、機能ベースのフォルダ名 レイヤーは論理構造、コロケーションは物理配置 ©MIXI Colocation https://kentcdodds.com/blog/colocation Clean Coder Blog https://blog.cleancoder.com/uncle-bob/2011/09/30/Screaming-Architecture.html 19 -
アプリアーキテクチャ まとめ: 実装時の心がけ • 責務は分離し、コードは局所化する • レイヤーと流れを意識する • 状態は単一の真実を持ち、UIはその結果として定義する •
構造でアプリケーションの目的を表現する 技術(フレームワーク)より先に設計、設計より先に目的 ©MIXI 20 -
アプリを”ひとまず”作ってみる はじめの一歩 • 1. 演習 好きな名前でFlutterプロジェクトを作ってみよう ◦ 2. 英小文字、数字、アンダースコアが使えます 起動してみよう
◦ iOSでもAndroidでもWebでも 実機・エミュレータのどちらでも大丈夫です ハイフンは使え ないことに注意 ©MIXI 22 -
アプリを”ひとまず”作ってみる Let’s Vibe Coding! 演習 1. DartPad https://dartpad.dev/ にアクセス 2.
「Flutter Snippet」から自然言語で作りたいアプリを説明 ◦ 3. lib/main.dart にコピー&ペースト ◦ 4. プレビューで確認しながら、気に入るまで「Update code」 必要ならパッケージのインストール (例: (flutter runを実行したterminal上で)r キーを押して Hot reload 、 R キーを押して Hot restart ©MIXI DartPad https://dartpad.dev/ 23 -
今回作るアプリの概要 簡易SNSクライアントを作ろう • • ©MIXI 主な機能 ◦ 投稿一覧機能 ◦ 投稿作成機能
◦ 投稿データはサーバーとリアルタイム同期 画面構成 ◦ / … ホーム画面(タイムライン) ◦ /compose … 投稿作成画面 25 -
今回作るアプリの概要 補足: 利用するSNSプロトコル • Nostrというプロトコルを利用 (Note and Other Stuff Transmitted
by Relays) ◦ WebSocketで接続できる分散型ソーシャルネットワークプロトコル ▪ ◦ • ©MIXI WebSocket … 双方向リアルタイム通信を維持するための常時接続プロトコル 投稿を含むあらゆるものをイベントとして、リレーによって送信する なぜ使うのか? ◦ 自前でプロトコルを定義しなくてよい ◦ 既存のリレーサーバーに繋ぐだけで”利用者の多いSNSアプリ”になる nostr-protocol/nostr https://github.com/nostr-protocol/nostr 26 -
UI構築 タイムラインのベースを作ろう • StatelessWidget ◦ 状態を持たないウィジェットの基本クラス 演習 1. lib/ 下に
pages/timeline/page.dart を作成して、 TimelinePage を作ってみよう 2. ©MIXI lib/main.dart から呼び出してみよう StatelessWidget class - widgets library - Dart API https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html 28 -
UI構築 タイムラインのベースを作ろう • StatelessWidget ◦ 状態を持たないウィジェットの基本クラス 演習 1. lib/ 下に
pages/timeline/page.dart を作成して、 TimelinePage を作ってみよう 2. ©MIXI lib/main.dart から呼び出してみよう StatelessWidget class - widgets library - Dart API https://api.flutter.dev/flutter/widgets/StatelessWidget-class.html 29 -
UI構築 FlutterのUI設計思想 • • Everything is a Widget ◦ 視覚要素(ボタン、テキスト)だけでなく、レイアウトや振る舞いなど全てがウィジェット
◦ コンポジション(合成)によって複雑なUIをシンプルに組み立てる 宣言的UI ◦ UI = f(state) の純粋関数的なモデルに基づく ◦ 状態が変化すれば、該当するウィジェットツリーを再構築する ◦ 明示的にUI更新ロジックを書く必要はない ◦ 再描画は差分検知で最適化される 「全てがウィジェットである」 ©MIXI Layout | Flutter https://docs.flutter.dev/ui/layout Inside Flutter | Flutter https://docs.flutter.dev/resources/inside-flutter 30 -
UI構築 2つの描画アーキテクチャ • FlutterはネイティブUIをラップしない。React Native等との差別点 • Skia • ◦ 長年利用されてきたクロスプラットフォーム2D描画エンジン
◦ CPU/GPU混在の柔軟なパイプライン ◦ パフォーマンスや安定性の面で限界があった Impeller ◦ Flutter独自開発の新しい描画エンジン ◦ Vulkan/MetalなどのモダングラフィックスAPIを積極的に活用 ◦ シェーダーの事前コンパイルで描画の一貫性とフレーム飛びを抑制 Flutter 3.27以降、iOSとAndroid API 29+でImpellerがデフォルトに ©MIXI Impeller rendering engine | Flutter https://docs.flutter.dev/perf/impeller 31 -
UI構築 投稿カードを作ろう • Material 3 ◦ Googleのデザインシステムで、Flutter標準採用 演習 1. lib/pages/timeline/
下に components/post_card.dart を作成して、 PostCard を作ってみよう • 2. ©MIXI Material 3 の Card と ListTile などが利用できそう! page.dart で PostCard を使ってみよう 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 32 -
UI構築 投稿カードを作ろう • Material 3 ◦ Googleのデザインシステムで、Flutter標準採用 演習 1. lib/pages/timeline/
下に components/post_card.dart を作成して、 PostCard を作ってみよう • 2. ©MIXI Material 3 の Card と ListTile などが利用できそう! page.dart で PostCard を使ってみよう 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 33 -
UI構築 アプリテーマを設定しよう 演習 1. lib/ 下に themes/colors.dart を作成して、 アプリ全体のカラーテーマを作ってみよう 2.
lib/main.dart の ThemeData に設定しよう 3. 余裕があれば themes/fonts.dart に アプリ全体のテキストスタイルを作ってみよう ©MIXI 34 -
UI構築 アプリテーマを設定しよう 演習 1. lib/ 下に themes/colors.dart を作成して、 アプリ全体のカラーテーマを作ってみよう 2.
lib/main.dart の ThemeData に設定しよう 3. 余裕があれば themes/fonts.dart に アプリ全体のテキストスタイルを作ってみよう ©MIXI 35 -
UI構築 デザインシステム • • • デザインシステムとは ◦ UIに一貫性と再利用性を与える設計のルール ◦ デザイナーと共通の”言語”を持つために不可欠
Material 3 の拡張性 ◦ UI構築に必要な要素が体系的に提供されている ◦ これをベースに、自分でデザインシステムを作っていける Flutterのデザインシステム ◦ UIの一貫性を保ちつつ、メンテナンス性を向上できる ◦ ThemeData を活用して色や文字のテーマを一元管理 クロスプラットフォームで統一感のあるUIを実現 ©MIXI Material | Flutter https://docs.flutter.dev/ui/widgets/material 36 -
状態管理とDI タイムラインに投稿を追加しよう • StatefulWidget ( + setState ) ◦ 状態を持つウィジェットの基本クラス
演習 1. TimelinePage に FloatingActionButton を 設置しよう 2. ボタンを押すと投稿がタイムラインに追加される ようにしてみよう ©MIXI 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 38 -
状態管理とDI タイムラインに投稿を追加しよう • StatefulWidget ◦ 状態を持つウィジェットの基本クラス 演習 1. TimelinePage に
FloatingActionButton を 設置しよう 2. ボタンを押すと投稿がタイムラインに追加される ようにしてみよう 押すと投稿が 追加される ©MIXI StatefulWidget class - widgets library - Dart API https://api.flutter.dev/flutter/widgets/StatefulWidget-class.html 39 -
状態管理とDI Flutterにおける「状態」とは? • UIやリソース管理に関わるオブジェクト • ユーザーの操作や外部イベントによって変化する • UIを構築するためのSSOT(信頼できる唯一の情報源)として扱われるべきもの ◦ 効率的に組織して管理する必要がある
状態はUIのSSOTである ©MIXI State management | Flutter https://docs.flutter.dev/get-started/fundamentals/state-management 40 -
[再掲] アプリアーキテクチャ [再掲] データの流れ • • ©MIXI Single Source of
Truth(SSOT, 信頼できる唯一の情報源) ◦ 各データ型は唯一の責務を持つクラスで管理 ◦ 同じデータを複数箇所で保持しない。バグを抑制 Unidirectional Data Flow(単方向データフロー) ◦ ユーザー操作は UI → ロジック → データ の順にイベントとして処理される ◦ 逆に状態は データ → ロジック → UI の順に流れる ◦ 状態の更新は常にデータ層(SSOT)を通じて行う Architecture concepts | Flutter https://docs.flutter.dev/app-architecture/concepts 41 -
状態管理とDI 2つの「状態」 • • ©MIXI Ephemeral State(ローカル状態) ◦ 単一ウィジェット内で完結するもの ◦
UIの一時的な状態。アニメーション進行度など App State(グローバル状態) ◦ アプリ全体で共有されるもの ◦ ページ間で情報は共有されるべきであるため、モバイルアプリはApp Stateが多い Differentiate between ephemeral state and app state | Flutter https://docs.flutter.dev/data-and-backend/state-mgmt/ephemeral-vs-app 42 -
状態管理とDI setStateの限界 • 状態が複数のウィジェットにまたがると管理が難しい ◦ • 状態がウィジェットに埋め込まれると再利用が難しい ◦ • 親から子ウィジェットへの伝播が煩雑
ロジックとUIが密結合し、可読性も低下 アプリケーション全体の状態を一元管理できない ◦ グローバルに共有すべき状態に対応不可 setStateはローカルには有効だが、アプリ全体の設計には不十分 ©MIXI 43 -
状態管理とDI グローバル状態の管理とRiverpod • 状態管理ライブラリは複数あるが、特に日本語圏ではRiverpodが代表的 • なぜ Riverpodを利用するのか • ©MIXI ◦
状態とUIを分離できる ◦ UIとロジックのテスト性を向上できる ◦ 非同期や複数画面でも簡単に状態管理できる Riverpodの仕組み ◦ 状態をプロバイダー経由で注入 ◦ UIは必要な状態だけを監視すれば良い Riverpod https://riverpod.dev/ 44 -
状態管理とDI Riverpodで書き換えよう 演習 1. flutter_riverpod を依存関係に追加する 2. ProviderScope を main.dart
に追加する ©MIXI ◦ スコープ単位で状態の分離ができる ◦ 今回はアプリのエントリーポイントに配置 Riverpod https://riverpod.dev/ 45 -
状態管理とDI Riverpodで書き換えよう 演習 3. lib/pages/timeline/ 下に provider.dart を作成して、 timelineProvider を作ろう
4. TimelinePage を書き換えよう ©MIXI Notifier class - riverpod library - Dart API https://pub.dev/documentation/riverpod/latest/riverpod/Notifier-class.html 46 -
状態管理とDI Riverpodで書き換えよう 演習 挙動に変化が なければOK 3. lib/pages/timeline/ 下に provider.dart を作成して、
timelineProvider を作ろう 4. TimelinePage を書き換えよう ©MIXI Notifier class - riverpod library - Dart API https://pub.dev/documentation/riverpod/latest/riverpod/Notifier-class.html 47 -
状態管理とDI DI (Dependency Injection) • • DIとは? ◦ 依存関係(= 他のオブジェクトやリソース)を外部から提供する設計手法
◦ オブジェクトが自ら依存対象を生成せず、外部から受け取る ◦ 保守性・テスト容易性・再利用性の向上につながる RiverpodとDIの関係 ◦ プロバイダーがDIのユニットになっている ◦ 依存オブジェクトを定義し、必要な場所で注入する設計 構造を明示的にし、アプリの保守性を支える ©MIXI Providers | Riverpod https://riverpod.dev/docs/concepts/providers#why-use-providers 48 -
非同期値の取り扱い 投稿の中身 • WebSocketでリアルタイムに投稿を受け取る • 投稿データは簡単なJSONイベントになっている ©MIXI nips/10.md at master
· nostr-protocol/nips https://github.com/nostr-protocol/nips/blob/master/10.md 50 -
非同期値の取り扱い 投稿データモデルを定義しよう 演習 • lib/ 下に entities/post.dart を作成し、Post を定義 •
JSONイベントをDartで扱えるようにしよう ©MIXI 51 -
非同期値の取り扱い AsyncNotifier / StreamNotifier • 非同期状態管理のためのNotifier派生型 • 状態は AsyncValue<T> で管理され、ローディングやエラーを明示的に扱える
• AsyncNotifier • ◦ 一過性の非同期処理に最適(初回ロード、操作後の更新など) ◦ 呼び出しごとに処理が完結し、開始を明示的に制御できる StreamNotifier ◦ 継続的な状態変化を扱う(WebSocketの購読など) ◦ ストリームに流れるデータをリアクティブに処理したい場合に適する 一過性の非同期処理にはAsyncNotifier, 継続的な変化にはStreamNotifier ©MIXI 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 52 -
非同期値の取り扱い 投稿データを取得しよう 演習 1. web_socket_channel を依存関係に追加 ◦ 標準の dart:io を使っても良いが、
クロスプラットフォーム対応したい 2. StreamNotifier で timelineProvider を 書き換えてみよう • 研修のために用意したリレーサーバーのURLは Slackに貼ります ©MIXI 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 53 -
非同期値の取り扱い 投稿データを取得しよう 演習 型が変わる ことに注意 3. ウィジェットに反映しよう • 研修リポジトリの server/
を見て、ローカルに リレーサーバーを立ててもOK • 動作に問題がなければ実世界のリレーサーバーに 接続しても勿論OK ©MIXI AsyncValue class - riverpod library - Dart API https://pub.dev/documentation/riverpod/latest/riverpod/AsyncValue-class.html 54 -
非同期値の取り扱い 投稿データを取得しよう 演習 型が変わる ことに注意 3. ウィジェットに反映しよう • 研修リポジトリの server/
を見て、ローカルに リレーサーバーを立ててもOK • 動作に問題がなければ実世界のリレーサーバーに 接続しても勿論OK タイムラインは 自動で更新される ©MIXI AsyncValue class - riverpod library - Dart API https://pub.dev/documentation/riverpod/latest/riverpod/AsyncValue-class.html 55 -
ルーティング 投稿作成画面を作ろう • ConsumerStatefulWidget ◦ ConsumerWidget + StatefulWidget 演習 •
投稿作成画面を作ってみよう • 投稿送信処理は今は空でOK ◦ ©MIXI 非同期処理を行う予定なので AsyncNotifier 57 -
ルーティング 投稿作成画面を作ろう • ConsumerStatefulWidget ◦ ConsumerWidget + StatefulWidget 演習 •
投稿作成画面を作ってみよう • 投稿送信処理は今は空でOK ◦ ©MIXI 送信ボタンを押しても 内容が消えない =状態が保持されている 非同期処理を行う予定なので AsyncNotifier 58 -
ルーティング ルーティングとは? • 画面遷移の定義と制御を行う仕組み • 2つのアプローチが存在する ◦ Navigator … 命令的ルーティング
▪ ◦ push() / pop() を用いて遷移する Router … 宣言的ルーティング ▪ URLベースの定義。Web対応するならほぼ必須 ▪ go_router などライブラリを利用することが推奨されている • ©MIXI パラメーター・クエリ・遷移アニメーション対応 Navigation and routing | Flutter https://docs.flutter.dev/ui/navigation 59 -
ルーティング go_router で画面遷移 演習 1. go_router を依存関係に追加 2. lib/ 下に
router.dart を追加し、 router を定義 3. main.dart で router を設定 4. 各ページで遷移先を指定 ◦ ©MIXI context.push() / context.pop() が使えます 60 -
ルーティング go_router で画面遷移 演習 1. go_router を依存関係に追加 2. lib/ 下に
router.dart を追加し、 router を定義 3. main.dart で router を設定 4. 各ページで遷移先を指定 ◦ ©MIXI context.push() / context.pop() を使います 61 -
送信処理 Nostrの投稿には署名が必要 • 投稿データ = JSONイベント • 秘密鍵で署名する ◦ •
秘密鍵を保存する(=ユーザー作成機能をつける)なら ◦ ©MIXI bip340 … Schnorr署名に準拠したライブラリ flutter_secure_storage … セキュアにローカルにデータを保存するライブラリ bip340 | Dart package https://pub.dev/packages/bip340 flutter_secure_storage | Flutter package https://pub.dev/packages/flutter_secure_storage 63 -
送信処理 投稿しよう 演習 1. bip340 を依存関係に追加 2. 秘密鍵の生成、イベント署名など関数を用意 utils/nostr.dart など
©MIXI bip340 | Dart package https://pub.dev/packages/bip340 64 -
テスト アーキテクチャとテストの関係性 • テストしやすい設計とは? ◦ 状態とUIの責務が分かれている ◦ ロジックがウィジェットから独立している ◦ DIにより依存対象を差し替えられる
今まで作ってきた構造は、すでに「テストしやすい」状態にある ©MIXI 67 -
テスト Flutterにおけるテストの種類 (1) • • ©MIXI 単体テスト ◦ 小さな単位のロジックを検証 ◦
ランタイムが高速 ◦ アプリの核となるロジックを高速かつ確実に保証する ウィジェットテスト ◦ Widgetの表示内容や操作に対する動作を検証 ◦ 中程度の速度 ◦ UIが意図通りか、操作に応答するかを局所的に確認する 68 -
テスト Flutterにおけるテストの種類 (2) • • ©MIXI ゴールデンテスト ◦ 見た目が意図通りかを画像として検証 ◦
基準画像(ゴールデンファイル)とのピクセル差分比較 ◦ デザインの不整合をCIで早期に検出する 統合テスト ◦ アプリ全体の動作を検証 ◦ ユーザーが実際に操作する流れをシミュレートする ◦ ネットワーク通信や画面遷移の一貫性を保証する 69 -
テスト ウィジェットテストを書いてみよう 演習 1. タイムラインから投稿画面への画面遷移のテストを書いてみよう 2. 余裕があるなら投稿作成のテストを書いてみよう ◦ ©MIXI ProviderScope(overrides:
) が利用できます ProviderScope class - flutter_riverpod library - Dart API https://pub.dev/documentation/flutter_riverpod/latest/flutter_riverpod/ProviderScope-class.html 70 -
テスト ゴールデンテストを書いてみよう 演習 • PostCard のテストを書いてみよう • alchemist https://pub.dev/packages/alchemist を利用するのが簡単です
©MIXI Betterment/alchemist: A Flutter tool that makes golden testing easy. https://github.com/Betterment/alchemist 71 -
テスト テストは銀の弾丸ではない • • ©MIXI 現実的な課題 ◦ テストは書いて終わりではなくメンテナンスする必要がある ◦ UI変更に追従できないテストはすぐ”腐る”
◦ (特にフロントエンドにおいて)TDDが必ずしも生産性を上げるとは限らない 現実的な運用 ◦ 価値の高い箇所に重点的に適用する。認証機能など ◦ カバレッジよりも、変更に強い構造を優先する 72 -
テスト CI/CD・監視 • • 自動化による品質維持 ◦ テストはCIでの検証を前提にする ◦ PR単位でのフィードバックで修正コストを抑える ◦
本番環境を見据えたビルド検証や段階的リリース テストで補えない領域への対応 ◦ テストが補足できない問題(パフォーマンス、設定ミスなど)も多い ◦ メトリクス・ログ・トレースを使った継続的なシステム監視 テストだけに依存しない設計と運用の仕組みが品質を支える ©MIXI 73 -
UI品質保証 ゴールデンテストの限界と代替案 • • ゴールデンテストの課題 ◦ UIの見た目を画像で保証 → 画面変更に脆弱 ◦
画像差分が生じるとfalse positive(偽陽性)が頻発 ◦ 実際に「目で確認したい」だけのケースも多い UIカタログがその代替になり得る ◦ ©MIXI FlutterだとWidgetbookが代表的 Widgetbook - Review all UI changes of your Flutter app in seconds https://www.widgetbook.io 75 -
UI品質保証 Widgetbookとは? • Flutter製のUIカタログツール • 各コンポーネントの「状態違い」を一覧で表示できる • Webで言うStorybookのような、開発者(+ デザイナー)向けツール •
UIパーツの集約場所として活用できる ©MIXI 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/ 76 -
UI品質保証 monorepo + design system • design_system を中心に、client と ui_catalog
でUIを共有 • UIとロジックの分離を強制しやすい ©MIXI 77 -
UI品質保証 追加演習: Widgetbook を導入しよう • • ©MIXI 演習 Widgetbook で投稿カードを表示してみよう
Widgetbook - Review all UI changes of your Flutter app in seconds https://www.widgetbook.io 78 -
UI品質保証 実務での適用戦略 • • UIテスト・レビューの実務構成 ◦ デザインシステムの運用 ◦ ゴールデンテスト +
UIカタログ + QA UIが壊れてないことだけでなく、 「意図通りに表示されているか」を確認したいならUIカタログが有効 ©MIXI 79 -
Flutter以外の選択肢と技術選定力 技術選定でまず考えるべきこと • • ©MIXI 最初に問うべきこと ◦ そもそもアプリを作るべきなのか? ◦ ユーザーはどのような体験を求めているのか?
◦ 何に対して一番コストをかけるべきか? 技術(フレームワーク)は目的を達成するための手段に過ぎない 81 -
Flutter以外の選択肢と技術選定力 Flutterを選ぶときの判断軸 • • Flutterを選ぶなら ◦ 目的が「スピード」「複数OS対応」「UIの統一性」である ◦ Dart/Flutterの設計思想に共感できる Flutterに固執しない
◦ ネイティブを選択しない損失を理解する ◦ 他のクロスプラットフォームフレームワークも正解になり得る ▪ 例: すでにWebアプリがありバックエンドがNode.jsで書かれている → React Nativeが有力候補 技術選定の前に、事業の前提を見直す ©MIXI 84 -
Flutter以外の選択肢と技術選定力 まとめ • 技術選定の本質は前提と制約の理解 ◦ 誰のために、どんな価値を提供したいのか? ◦ 何を優先して、どこを妥協するか? ◦ 運用体制(人・時間・資金)は現実に即しているか?
• Flutterは強力なツールだが、万能ではない • 技術から始めない、目的から始める 「何を作るか」「どう運用するか」 ©MIXI 85 -
まとめ・振り返り この研修で得たもの • UI構築 ◦ • • 状態管理 ◦ ローカル状態とグローバル状態
◦ ネットワーク通信、非同期処理 テスト ◦ • 4つのテスト手法、現実的な適用法 技術選定 ◦ ©MIXI 宣言的UI、デザインシステムとコロケーション 目的から技術を選ぶ視点 88 -
まとめ・振り返り 実際の現場でどう応用するか? • プロトタイピング ◦ • 設計・レビュー ◦ • アーキテクチャ、状態とUIの責務分離をレビューできる
技術選定 ◦ ©MIXI Flutterならあらゆるプラットフォームで即座に動く画面が作れる 「Flutterにする?しない?」を根拠をもって議論できる 89 -
おまけ 「ぼくのかんがえたさいきょうのSNS」を作ろう • • 今日作ったアプリは… ◦ WebSocketで実際のソーシャルネットワーク (Nostr) と接続している ◦
任意のリレーサーバーにアクセスすれば、リアルタイムに人の投稿が見える ◦ UIや機能を拡張すれば、公開可能なSNSクライアントになる あとは: ◦ ©MIXI いいね、リアクション、フォロー機能、プロフィール編集、ダイレクトメッセージ.... 90