Fluttercon 2025 Day 2:自分の知らない世界を見つけた

こんにちは👋 イベントレポート早速出してる
アプリチームのルーカス (YOUTRUST / X) です

正直、初日の夜はかなり疲れてしまって、Flutterconの熱気と初日のブログ の執筆でぐったりしてました(笑)。翌朝はチーズブレッツェルを片手に会場へ向かい、ちょうどDay2が始まる前に記事を公開!

今回、できるだけイベント直後に記事を出してる理由は、現地に来れなかった人たちにもFlutterコミュニティの熱さを感じてもらいたいからです。こんなコメントをもらえると本当に嬉しい…!

Ericのキーノート

2日目の最初は、Flutterのプロダクト責任者であるEric Seidelさんによる基調講演からスタートしました。

2024年にはiOSの無料新規アプリの30%がFlutter製だったというデータがApptopiaから紹介され、Flutterの成長と普及を改めて実感しました。

今回の講演テーマは「The Future is Written in Dart」。

Ericさんは、エンジニアとしてのキャリアを「ドグマ(原理主義)ではなく、プラグマティズム(実用主義)」で築いてきたと語っていました。これは、私が尊敬するLeanCodeの開発スタイルにも通じる考え方で、個人的にとても共感しました。

彼が今Flutterに対して感じている課題は、たとえば以下のようなもの:

  • データクラスやJSONの取り扱いの改善
  • ビルドの高速化

でも、ただそれだけでは業界全体の未来は変えられないとも考えているそうです。

彼が目指すFlutterの未来像は、もっと大きなビジョンに基づいています:

  • Xcode不要でFlutterをインストール&使用できるようにする
  • 複数のプラットフォーム間でコードをもっと共有しやすくする
  • クライアントとサーバーを同時にデプロイできるようにする
  • Webとモバイルの両方で、UIをリアルタイムプレビューできるようにする
  • Flutter/Dartをより多くのプラットフォームへ、分岐せずに展開できる未来

これらを実現するために、彼はShorebirdを離れ、自らが本当に作りたい未来のために新たなチャレンジに踏み出しました。

講演の最後では、GPay(Google Pay)がFlutter導入によって3倍速くなった事例や、プラットフォームチームではなく、機能ごとのチームでアプリを作っているという組織面での改善も紹介され、Flutterが単なるUIツール以上のものになっていることが感じられました。

Flipping the Testing Pyramid - Smarter Widget Testing with Spot & Robots

このセッションは、Flutter GDEのPascal Welschさん(ドイツ出身)によるものでした。 「多くの人がテストは難しいと感じており、その結果としてテストを書かない」という現実に切り込む、とても実用的で考えさせられる内容でした。

まず紹介されたのが、Mike Cohnの有名なテストピラミッドの概念です。

Testing Pyramid by Mike Cohn

  • 単体テスト(Unit Test):特定の機能単位を検証する
  • サービステスト(Service Test):UIを含まず複数のワークフローを横断的に検証
  • UIテスト(UI Test):ユーザーインターフェースを通してアプリ全体の動作を検証

Flutterでは独自に「テストピザスライス」という考え方があるそうで、Pascalさんは統合テスト(Integration Test)をあまり推奨しないスタンスでした。

テストを書くときに本当に意識すべきことは「数」ではなく「質」。以下の5つが良いテストの条件です:

  • 分離されている(Isolated)
  • 信頼性がある(Reliable)
  • 高速(Fast)
  • 決定論的(Deterministic)=実行するたびに結果が変わらない
  • デバッグしやすい(Easy to debug)

🧨 E2Eテストの厳しい現実

Pascalさんは、E2E(End to End)テストには多くの課題があることを率直に語ってくれました。

まず、エミュレータやシミュレータは不安定でよくクラッシュすることがあります。また、OSや周辺システムがアップデートされることで、テストが突然通らなくなることも日常茶飯事です。

さらに、認証情報(APIキーやトークンなど)はしばしば管理が複雑になり、外部委託の契約終了などでリポジトリの移行中に失われてしまうケースもあります。

CI/CD環境でE2Eテストを動かすには多くの準備が必要で、新しいCI環境に移行する際には設定の再構築が非常に大変です。テストの実行自体もリアルタイムで行われるため、ビルド時間が極端に長くなりがちです。

そして最も問題なのが、「テストが失敗したときに誰も責任を取りたがらない」という現実。誰かが「一時的な問題かも?」とスルーしてしまうと、そのまま放置され、次第に信頼されないテスト群になっていきます。

Widget Testを進化させる:Spot

最後にPascalさんは、Widget TestのUXを大幅に向上させるライブラリ「spot」を紹介してくれました。

  • どこで失敗したかを明確に出力
  • 自動スクリーンショット機能あり(文字付き)
  • Font Manifestを使って適切なフォントも読み込み可能
  • takeScreenshot() 関数で簡単にUI状態をキャプチャ可能

pub.dev

Time for Flutter on the Apple Watch

Antonさんは、FlutterアプリとApple Watchを連携させる方法について詳しく解説してくれました。

最初に、UserDefaultsを使えばデータ共有できるのでは?と思っていたそうですが、それは初代Apple Watchの話で、現在では使えません。代わりに使うべきは…

✅ WatchConnectivity フレームワーク!

このフレームワークを使うことで、以下のようなデータ連携が可能になります:

  • ファイル送信
  • ユーザー情報の送信
  • メッセージの送受信
  • applicationContext による状態共有

Flutterにはこれらの機能をラップした watch_connectivity パッケージが存在しており、それを使えば連携は比較的スムーズに行えます。

🔧 実装ポイント

  • watchOS側では WCSessionDelegate を作成し、受信処理を実装
  • Flutterアプリ側では updateApplicationContext で情報を送信し、iOS側で didReceiveApplicationContext を使って受信 • Apple Watchからも updateApplicationContext を使ってデータ送信可能

🖼 Flutter UI を表示するテクニック

Flutterアプリ内で screenshot widget を使ってUIを画像として保存し、その画像をApple Watchに送信して、Flutter風のUIをWatch上に表示することも可能です。クリエイティブ!

🧩 Complications(コンプリケーション)にも対応

Apple Watchでは Complications という仕組みを使って、小さな情報ウィジェットを文字盤に表示することができます。このデータも userInfo 経由で送信できます。

📱 watchOSアプリは意外と簡単に構築できる!

Antonさんは、watchOSアプリ自体も思っていたよりスムーズに作れたと語っており、Flutter開発者がApple Watch対応に挑戦するハードルは確実に下がっている印象でした。

🧠 Flutter&クロスプラットフォームクイズチャレンジ!

Flutterconでは毎日開催されている「ナレッジクイズ」というイベントがあって、Flutter・Dart・クロスプラットフォーム開発全般に関する知識を競う、スピード勝負の早押しクイズです。

ルールは「速く正確に答えるほどスコアが上がる」

……のはずだったんですが、見事に失敗しました😂

Flutterクイズでは10問中2問をミスってしまい、不合格に。 内容は一見シンプルだけど意外と罠が多い質問ばかりで、例えば:

  • ❓ Flutterという名前になる前は何と呼ばれていた?
  • ❓ Dartが最初に発表されたのは何年?
  • ❓ Fluttercon 2025の登壇者数は?

今年の登壇者、96人だと思ってたんですが、正しくは75人でした…。 あと完全にやらかしたのが「ヒットテストに関わるツリーは?」という質問。 「Gestureツリー!」って自信満々で答えたんですが、正解は「Layerツリー」でした。惜しい…惜しくない…?😂

💥 Flutter vs KMP vs React Native 〜クロスプラットフォームの戦い〜

もう一つのクイズは、Flutter vs Kotlin Multiplatform vs React Native vs 世界という、まさに「クロスプラットフォーム頂上決戦」みたいな内容。

こちらはなんとか6位にランクインして、Kotlinのぬいぐるみをゲットできました🎉 初めて聞いたツールもあって、SkipやGoMobileという新しめのクロスプラットフォーム技術の存在を知ることができたのも良かったです!

クイズは知識だけじゃなくて、意外と反射神経も問われるので毎回ドキドキしますが、 自分の知識の穴を知る良い機会にもなるし、なにより楽しい。 来年参加する方は、ぜひ挑戦してみてください!

Hossein Yousefiさんとffigenの話

今回のカンファレンスで一番勉強になったのは、GoogleでFlutterのFFI関連(jnigen, ffigenなど)を担当しているHossein Yousefiさんとの会話でした。

実は僕、以前ffigenを使ってObjective-Cのバインディングを自動生成したことがあったのですが、今回の出力結果が以前と全く違っていて混乱していました。そこでHosseinさんに相談したら、こちらのリポジトリを教えてくれました👇

github.com

この中には多くのサンプルが入っていて、今後の勉強や登壇準備にすごく役立ちそうです。

ffigenとは?

知らない人のために簡単に説明すると、ffigenはCやObjective-Cのヘッダファイルを読み取って、DartのFFIで呼び出せるバインディングコードを自動生成してくれるツールです。

ただし、まだSwiftは完全対応していないのが現状です。新しいApple APIはSwift専用で提供されるものも多いため、その対応策としてSwiftGenが作られました。仕組みとしては:

  1. Swiftコードを読む
  2. 新しいSwiftコードを生成する
  3. それをObjective-Cクラスに変換する
  4. DartのFFIから呼び出せるようにする

という流れで、実際にかなりうまく動いているそうです。これを聞いたとき、正直「すごい…」と感動しました。

Swift 6に変わったらどうなる?

僕が一番気になったのは、「SwiftがSwift 6に変わったらバインディングは壊れるのでは?」という点でした。

Hosseinさんの答えはNo。 理由はシンプルで、実装そのものではなく関数のシグネチャ(型情報やメソッド定義)だけを見ているから。しかもAppleは公式にこのシグネチャ情報をドキュメント生成にも利用しているそうです👇

github.com

WeakMapとExpando

さらに面白い豆知識も教えてもらいました。

  • DartとSwift/JavaではGC(ガーベジコレクタ)の仕組みが違うため、FFI内部ではWeakMapやExpandoといった仕組みが活躍しているとのこと。
  • WeakMap 特定のキーに値を紐付けて保持できるが、参照が不要になったらGCが自動でクリアしてくれる。
  • Expando 既存のオブジェクトに動的に新しいプロパティを付与できる。

普段あまり意識しない部分ですが、FFIの裏側ではこういう工夫がされているのだと知れて面白かったです。

Hosseinさんは本当に優しくて、20分くらい丁寧に説明してくれました。 技術的な深い話をわかりやすく噛み砕いて伝えてくれる方で、とても楽しい時間でした。

LeanCode AI Coding Challenge

今回のカンファレンスで個人的に一番楽しみにしていたのは、LeanCode(最も好きなFlutterの会社)のブースで行われていたAIコーディングチャレンジでした。

内容はシンプルで、「AIだけを使って新しい機能を実装する」というもの。実際に触ってみると、彼らが社内で開発しているLeanAIを使わせてもらえました。これは現在フィードバック収集中とのことですが、本当に賢いアイデアだと思いました。

LeanCodeはパッケージ数も多く、アーキテクチャやコーディングスタイルがとても厳密に決められています。だからこそ「誰が書いても同じ品質・同じスタイルを保てる」ように、このLeanAIを作ったそうです。正直、YOUTRUSTでも欲しい!と思いました。最近チームが大きくなってきて、スタイルのバラつきをどう揃えるかは課題になりつつあるので。

チャレンジをクリアした報酬として、Patrolマグカップをゲット!これからオフィスでガンガン使わせてもらいます☕️ さらにPatrolの今後の開発ロードマップについてもニュースを聞けたので、ここで3つシェアします👇

  • 🛠 Patrol IDE Extension → IDEに統合され、さらに使いやすく!
  • 🌐 Patrol MCP Server → マルチコンポーネントの自動化が進む!
  • 💻 Flutter Web サポート → 待望のWeb対応が実現!!

Server-Side Rendering for Flutter Web: Promising Paths or Dead End?

このセッションは、Flutter WebにおけるSSR(Server-Side Rendering)の可能性と課題についての探究でした。

🌐 なぜFlutter Webを使うのか?

  • ネイティブアプリだけでなくWeb版を提供したい
  • ユーザーがWebを好む/必要とするケースがある
  • トライアルやステークホルダーへの低ハードルなプレビュー環境を提供できる

📈 Webで重要なこと

  • SEO & GEO最適化
  • ローディング時間の改善

ローディング改善のテクニック

  • index.html にローディングインジケータを追加してUX向上
  • アイコンのTree Shakingでバンドルサイズ削減
  • 画像は WebP/AVIF を優先、必要サイズだけロード
  • API・フォントに preconnect を設定
  • アセットは gzip/brotli圧縮(特にWasmは必須)
  • キャッシュポリシーをハッシュ付きアセットに設定
  • sitemap.xml と robots.txt を用意

構造改善

  • リアルURL戦略を導入 → /about 形式(flutter_web_plugins/url_strategy)
  • サーバーでURLリライトを有効化
  • Semanticsウィジェットを活用 → クローラー対応
  • dart:html を使って meta title / description / og data を設定

📝 HTML出力でできること

  • 各パスごとに メタデータを提供
  • ページの HTML版を代替として提供
  • schema.org構造化データ(JSON-LD)を追加

❌ SSRの難しさ

理想はこうです👇 「ユーザーがページにアクセス → サーバーが完全なHTMLを返す → ブラウザはそれを即表示 → バックグラウンドでFlutterバンドルをダウンロード → 最終的にCanvasレンダリングに置き換え」

しかし実際は問題だらけ。

  • 旧HTMLレンダラを試したが、出力はただの絶対配置divタグで構造がなくダメ。
  • Semantics出力は構造だけ得られるが、デザインは消失。
  • BuildメソッドをハイジャックしてHTML文字列を返そうとしたが、複雑すぎる。
  • Flutterをフォークして独自ターゲットを作成しようとしたが、難易度が高すぎて断念。
  • AIパーサー方式 → スクリーンショットからHTML/CSSを生成。だが画面外の情報は欠落。

最終的には「スクリーンショットを提供しつつ、裏でFlutterアプリを走らせる」という苦肉の策で一応実現。

🚧 まとめ

まだ完全解決には至っていませんが、Flutter WebにおけるSSRは非常に興味深い研究テーマであり、今後の発展が期待される領域です。

🍻 アフターパーティー @ アイリッシュパブ

カンファレンスの長い一日を締めくくるのは、やっぱりみんなで乾杯。 この日は何人かの参加者と一緒に アイリッシュパブ へ行きました。僕はドイツ定番の飲み物 Spezi(オレンジジュース+コーラのミックス) を注文。これがまた美味しいんです。

♿ アクセシビリティの問題

パブでの会話の一つは、最近の Flutterにおけるアクセシビリティ課題 についてでした。 現状、Flutterにはまだバグが多く、十分にアクセシブルとは言えない部分があります。これは特に ヨーロッパ圏 では大きな問題です。なぜならEUは法律でアクセシビリティを厳しく求めているからです。しかもFlutterはヨーロッパで広く使われています。

もしFlutterがこの要件を満たせなければ、将来的に採用が難しくなるかもしれません。 冗談で「それなら自分たちでFlutterをフォークして修正するしかないな」なんて話にもなりましたが、もちろんそんなスキルは持ち合わせていません(笑)。

🏛️ Flutter Foundationのアイデア

もう一つ話題になったのは、Flutter Foundation(フラッター財団) を設立する案です。

  • Googleが優先していない課題を扱うために、コミュニティの主要メンバーが理事会を構成
  • 企業から寄付を募り、オープンソース活動を支援(非営利団体的に運営)
  • 集まった資金は、コミュニティの取り組みやFlutterリポジトリのメンテナーへの報酬に充てる
  • 認定資格制度を設けて、企業がFlutterスキルを持った開発者を見分けられるようにする

こうした仕組みがあれば、Flutterの未来を Google依存から脱却 させつつ、もっと持続可能にできるのではないか?という前向きな議論でした。

これがまだ2日目だなんて信じられないくらい、重要なトークや学びがたくさんありました。 特に強く感じたのは、自分にはまだまだ学ぶべきことが山ほどある ということ。

でも、それこそが僕がFlutterを好きな理由の一つです。 「自分に足りないものを知り、そこを一つずつ埋めていく」──その過程が楽しくて仕方ない。

もっともっとFlutterを学び、使いこなしていきたいと思います。 🚀💙