FlutterKaigi2023
先月10日、FlutterKaigi2023が開催されました。
当日、私は運営メンバーとして当日参加していた為、あまりセッションを聞く時間がありませんでした。
しかし!嬉しいことに、その後Youtubeにて見逃し配信が公開されておりましたので、その内容をご紹介したいと思います!
登壇資料については、いせりゅーさんがまとめてくだすってたので併せて御覧くださいませ
https://qiita.com/isekiryu/items/f1ebf59715507fafc120
Session内容
1. Congratulatory Speech and 基調講演(Flutter's 8 years journey)
なんと、Flutter開発者のAndrew Brogdonさんが海外からのビデオレター!
背景がちょっと気になりますが(笑)、本当に嬉しいスペシャルサプライズですね!
najeiraさんより、Flutter登場から8年の歩み。
Google主催のカンファレンス(DartSummit、Google I/O)をポイントに各年どのような動きがあったか振り返って頂きました。
sky_engineから始まり、BLoC、Web対応、null safetyなどを経て今に至るという内容
個人的に、Flutter初期は中華系起業(Alibaba、Tencent等)が多く採用していたという点が興味深かったです。
2. Flutterアプリにおけるテスト戦略の見直しと自動テストの導入
WINTICKETのテスト戦略について解説
当セッションは、テスト戦略としてみたら、Flutter以外のどのプロダクトでも通用する内容なのかなと思います。
テストの目標設定から現状分析、対応方法検討、実践導入という流れで話が進み、それぞれの動機決定が全て理由付けされてます。
Flutter領域では、下記ポイントがすごく参考になりました
- integration_testの強化として、RobotPattern、OSのUI部分操作方法(Patrol等)
- E2E Test時に失敗するケース(APIレスポンス取得のwait、tap対象検出失敗)への対応策
3. Master of Flutter lifecycle
Flutterの3つのlifecycleとして、WidgetLifecycle、AppLifeCycle、Navigation&Routingを整然とわかりやすくまとめてくれてます。
AppLifeCycleについては、flutter3.13.0にてhiddenが追加されました。その背景はmacOSやLinux対応だそうで、3.13前後でのAppLifecycleにどういった変化があったのか、各イベント毎にわかりやすく解説されてます。
最後には、AppLifecycleListenerとNavigationObserverを組み合わせ、アプリ内全てのlifecycleをハンドリングするサンプル紹介もありました
https://github.com/AAkira/flutter_lifecycle_example
4. Dartのコード自動生成の仕組みと、コード自動生成のパッケージを自作する方法について
Flutterで特徴的なコード生成パッケージ(freezed、json_serializable等)がどのようにコードを生成しているか、その裏側を解説されてます。
コード生成の仕組みの概要(セッションより引用)として、下記のpackageが必要となりそれらの実装内容を説明されました
- build_runner:Dartでコード生成を実行するために最もよく使われるパッケージ
- build:build_runnerパッケージでコード生成を実行する内容やロジックを実装する
- build_config:build.yamlで規定するコード生成の設定を記述する
- analyzer:静的解析のしくみで、生成対象や各種設定をパースするために使用する
- dart_style:生成されたコードの整形に使用する
- source_gen:analyzerパッケージやbuildパッケージを利用しやすくするAPIとして使用する
内容としては難しかったですが、用意頂いたsampleコードと併せて聞くと理解が早まるかと思います。
https://github.com/kosukesaigusa/code_generation_samples
5. Flutterで構築する漫画ビューア
Dモーニングで利用されている漫画ビューア開発の裏側を紹介
漫画ビューアって何かpackageがあるわけじゃなくて、全部自作なんですね
- 画像をFutureBuilderで読み込み、InteractiveViewerでページ拡大に対応。
- 拡大したままページめくりした場合の問題やダブルタップでのページ拡大への対応。
- DLしてきた漫画画像の漏洩を阻止する為の施策。
- 全画面表示のためのSystemUIMode解説。
- ページめくりアクションや指定ページへのjumpする方法。
- ページ見開きの対応。
と解説内容としては盛りだくさんで、どの内容も面白くて聞き入ってしまいました
個人的に、「漫画画像の漏洩を阻止」は結構いろいろな要所で必要になるんじゃないかと思いました。
6. 魅せろ!Flutterで目を惹くUIデザインを実装する
FlutterのUIを数段階引き上げる為、様々な施策でレベルアップを図るといった内容となります
その内容として、1つ目はRenderObjectのカスタマイズ。RenderObjectのカスタマイズとしては、独自のRenderObjectを作成、CustomPaintやCustomChildLayoutを利用しての方法を解説し、その用途比較を行いました。
その他方法として、Riveを用いた2Dアニメーション、FragmentShader、Impellerを利用した3DオブジェクトのFlutter取り込みについて解説いただきました。
個人的にはとてもワクワクする内容でして、こちらにて概要を把握し、Googleが提供しているFlutterNextGenUIsを辿ると、何か凄いアプリを作れそうですね!
7. 詳解!Flutterにおける課金実装
TokyoMixCurryの決済周りについて
前後半に分かれており、前半はサービスの全体紹介とコンシューマーが利用するアプリの決済について
元々はネイティブで実装されていたアプリをFlutterへ置き換える迄に至った経緯を説明いただき、今後Flutter移植を検討している方へ凄い刺さる内容なのかなと思います。
また、その中で発生した課題で「決済」機能をユーザーへストレスを与えること無く移植した経験や、Flutter化で受けた恩恵についても解説いただきました
後半は店舗に置かれているタブレット端末のセルフレジアプリの決済について
Square+Firebaseを利用した決済フローの解説。運用の中で発生した課題について、どういった解決を図ったかを解説いただきました。課題は凄い生々しい課題であり、解決方法などはきっと参考となる現場も多いかと思います
また、現場と一緒に課題を解決する姿がとても素敵なチームだなと思いました。
8. Custom Fragment Shaders
このセッションの内容は上級者向けなのかなと思います。
#6でも少し触れたFragmentShaderについて、その概要から始まり、GLSLの読み込み、画面への描画の内部実装について、実際のコードをベースに細やかに解説頂いております。
途中ffiを経由してC++のコード解説も入ってくるので、その部分が私には難しく感じました。
ただ、丁寧な解説いただいているおかげで、私のような初学者でもゆっくりと見直していけば、何となくの概要レベルは把握することは出来ると思います。
紹介されていたshaderのサンプルであるPixelationやHologram Effict、Ink Sparkle、Transitionのいづれもリッチなアプリを作成しようとするならば、覚えてておいて損はないテクニックじゃないかと思います!
9. Add Material touch ripples
ElevatedButton等でonTapする際に発生するエフェクトについての解説です
例えば、InkWellをタップした際にエフェクトが発生しなかったり、CardWidgetでonTapした際にエフェクトがborderRadiusを超えて発生する背景を知ることが出来ます。
_RenderInkReaturesやInkFeature等の普段気にしない領域にまで言及されており、とても深い内容でした
セッション内では当テーマでの過去記事も紹介されており、個人的にはこちらの記事を読んだ後に動画を見るのがおすすめです!
10. 出前館におけるFlutterの現在とこれから
出前館にはユーザー、加盟店、配達員向けの3アプリがあり、元々はそれぞれXamarin,ReactNaviveで作成されていた。それら全てをFlutterでの再構築(ReArchitect)しており、その中で今年ユーザー向けアプリが再構築完了したので、その大掛かりなプロジェクトを推進した内容をお話されました。
中でも、後半は再構築の中でも重要であったIntegrationTestでの取り組みを解説。
TestDisignとして、RegressionTestの海外論文(引用元が見つからず、、)を参考に、過去の不具合発生率、複雑さ、ユーザー利用率という指標でテストケースの順序を選定。また、ケース過不足チェックとしてUMLTestingProfileを作成してQAと一緒に見合わせを実施
結果として、大掛かりなプロジェクトだったけどバグ発生は収束し、無事にリリースまでたどり着いたという内容です。
IntegrationTestで出てきた専門的な話はどれも聞いたことが無く、また現在携わっているプロダクト開発にも取り込めそうであり、とても参考になりました!
11. DartによるBFF構築・運用 ~DartFrog×Melos~
BFFとはBackendForFrontendの略で、FrontendとBackendの中間に位置するサーバーを指す。
役割としては、例えば複数のBackendのAPIを一つに集約したい場合等に使われるらしく、私は初耳でした。
DartFrogはそのBFFの中でも現在主流のツールのようで、今回当該ツールの導入事例を紹介されております。
BFF導入事例もそう聞かないと思うので、当セッションはそういう意味でもとても貴重なセッションなのかと思います!
導入する中で、BFFリポジトリはマルチパッケージの構成にしており、アプリ間とのI/Fを担う"Json用の型"をpackage化して
アプリ側のdependencyに追加ということでI/F情報をシェアしているようです。
その流れで、マルチパッケージ管理に利用されていたMelosの紹介もされました。Melosはコマンドが充実しており、凄い使いやすそうです!
いづれのツールも名前を聞く程度の認識しか無かったのですが、こうやって導入事例をもとに経験を共有いただき、何となくの役割や使い方を把握できるのはとてもありがたいです!
また、セッション終盤にBFFのLiveデモもあり、かっこいいセッションでした!
12. ゆめみのFlutterエンジニア育成方法
エンジニア界隈では有名なyumemiのFlutterエンジニアの研修用リポジトリ内容を解説。
研修の流れとしては、下記12Sessionを通して一つの天気予報アプリを作るというもので、一見簡単そうだけど意外と難しいという内容が沢山見受けられました。
多分、Flutter歴2~3年くらいの方は一度やっておいたほうが良いんじゃないか、と思えるくらい内容の濃い研修でした。
- Session0-Setup
- Session1-Layout
- Session2-API
- Session3-Lifecycle
- Session4-Mixin
- Session5-Error
- Session6-JSON
- Session7-Serialization
- Session8-StateManagement
- Session9-UnitTest
- Session10-WidgetTest
- Session11-ThreadBlock
また、レビュー観点表もリポジトリに用意されており、普通にチームに導入を検討するレベル(勝手に導入して良いかは不明ですが…)
ゆめみさんって面白い会社ですが、こういった施策を打つところも、良い意味でとても面白いなと思いました!
https://github.com/yumemi-inc/flutter-training-template
13. Flutterアプリのセキュリティ対策を考えてみる
モバイルアプリのセキュリティ標準として著名なOWASP MASは、MASSV(セキュリティ標準)とMASTG(セキュリティテストガイド)が存在し、当セッションではMASSVのFlutterでの対応をフォーカスしております。内容としては、モバイルアプリ開発を行う上で、重要であるセキュリティ対策の一部分(適切なStorage管理、Network中間者攻撃への対策、スナップショット保存での情報漏洩、リバースエンジニアリング)を解説頂いております。
解説頂く中でもリバースエンジニアリングに関しては、前提として、Flutterがモバイル端末で動く仕組みの解説から始まり、実際にアプリを動的解析、静的解析する様子を披露され、実際にリバースエンジニアリングを試したりしたことが無かったので「こういう風に中身が覗かれるのか!」と食い入るように見てしまいました!
最後のまとめでも言及しておりますが、この動画内容はFlutterでのモバイルアプリ開発における、セキュリティ対策としての一部分の様でして、これを契機にOWASP MASを理解し、よりセキュアなアプリ開発を目指したいですね!
なお、OWASP MASVSであわせて見たいとして挙げていたセッションは英語だったので体力満タンの時に見させて頂きます…
https://github.com/owasp-ja
14. 我々はなぜRiverpodが必要なのか - InheritedWidgetから始めるapp state管理手法の課題
「Riverpodを採用した理由を説明できますか?」との問いかけから始まる当セッション。
前半はFlutterにおける状態管理の概要説明。後半は状態管理の課題に対するRiverpodの戦略という内容で、Riverpodが何故ここまで普及されているかを解説頂いております。
Widgetは必ず1:1の関係でElementを保持しており、状態はElement Tree側で保持している。
ざっくりと状態管理には2種類あり、主にStatefulWidgetが担うElement内に閉じた状態(ephemeral state)と、InheritedWidgetが担うapp全体から参照される状態(app state)。
どちらの状態においても、状態変化を起点にElementのmarkNeedsBuild()が呼び出され、対となるWidgetをRebuildすることによってUIが変化するという流れは変わらない。
なお、セッション内で案内されていた過去セッション「Everything is an "Element"」はこちらとなります。こちらをチェックいただくと、Elementに対しての理解がより深まると思います!
以上の前半のポイントを踏まえた上で、後半ではそんな状態管理で起きうる下記の課題に対してRiverpodがどのような戦略を取っているかが解説されます。
- 状態の生成、更新、破棄
- 状態同士の連携
- 非同期な状態の更新
- テスト
動画の尺は他よりちょっと長いですが、実際に聞いてみると全然足りないくらい濃い内容でして、あっという間に終わってしまいます。
Riverpodは今では主流の状態管理となり、そのRiverpodの解像度を上げるとても有用なセッションとなります。
まだ未閲覧の方がいらっしゃれば是非御覧くださいませ!
あとがき
登壇される方々が本当に凄い実力の方ばかりなので、セッション内容も本当に質が高いと思いました。
一通り聞いていると、色々と試してみたくなる内容ばかりで、モチベーションも上がりますね!
FlutterKaigiは今回、初のオフライン開催でした。
実際の現地では、様々なFlutterエンジニアと交流することが出来て私自身とても楽しかったです。
また来年も開催されると思うので、今からが楽しみですね!
運営としての参加レポもリンク貼っておきますので、運営側の視点にご興味あれば是非御覧くださいませ