[読書ノート] Flutter モバイルアプリ開発バイブル
2019年10月31日発売のFlutter モバイルアプリ開発バイブルという本を、著者の1人である 南里勇気さん(@neonankiti) から献本していただいたので、それを読んだ感想などを書いていきます。
Chapter1: Flutterとは
Flultterの魅力的な点の紹介がざっくり述べられています。また、宣言的UIフレームワークの例として、以下がコード付きで紹介されています。
- Appleプラットフォーム: SwiftUI
- Android: Jetpack Compose
また、既存のクロスプラットフォーム開発技術との比較もされていて、全体感が分かるようになっています。
個人的に少し違和感があったのは、以下の記述です。
公式サイトでは、3D描画にも将来的に対応すると言及されており、
出典のリンクの記載が無かったのですが、おそらく以下のことだと思います。
Can I build 3D (OpenGL) apps with Flutter?
Today we don’t support for 3D via OpenGL ES or similar. We have long-term plans to expose an optimized 3D API, but right now we’re focused on 2D.
https://flutter.dev/docs/resources/faq#can-i-build-3d-opengl-apps-with-flutter
「3D描画にも将来的に対応する」というより、「現状3Dの対応はしておらず、遠い将来3D対応の可能性もあるかも」程度に思っておいた方が良いと思います。具体的な対応予定はまだ何も立ってないので。
Redditのスレッドも参考になります。
一応Unity埋め込みは可能なので、3D機能を部分利用であれば、それを使う手もあります。
また、Unityのような3D表現(いわゆる3Dのゲームなど)が不可能というだけで、Transform WidgetとMatrix4など組み合わせて以下のような3D効果などは簡単にできるので、一般的なアプリでちょっとした立体感を持たせた表現などを組み込みたい場合は問題なくできることが多いはずです。
Chapter2: 開発環境の構築
2–1: インストール
公式ドキュメントの以下に分かりやすく書かれている内容かつ、常に最新の正確な情報なので、個人的にはそちらに頼るのをおすすめします。
どうしても英語に抵抗があるなら、以下の日本語記事などもおすすめです。
2–3: Flutterアプリケーションの作成
後半では初学者がてこずりそうな実機実行についてもフォローしていて、良いと思いました。
最後にコラムとして紹介されていたFlutter Studioは、個人的にはちょっとぽちぽちしただけで、Flutter学習や実開発にあまり貢献しないと思ったので特に試してみなくても良い気がしています。
似ているものとして、公式がHotUIとしてIDE統合のプレビューおよびそこからの編集操作などに対応を検討しているようで、こちらは楽しみです(HotUIについては、p.79で触れられていました)。
Chapter3: ウィジェット
3–1: ウィジェットの基本
まず、Flutterプロジェクト作成直後に生成されるmain.dartの雛形 を消して一から書きながらきちんとした理解を促す説明で良いと思いました。この雛形のカウンターアプリコードはいろいろ弄ると勉強になって良いです。
ただ、Themeについての言及が無かったのは残念でした。ダークテーマ対応などの必要性が高まりつつあり、その対応を手際良くこなすために大事な要素です。
3–2: レイアウトの構築
これに相当する内容です。
公式ドキュメントには、埋め込みDartPad活用してサンプルコードを実行・編集できるページもあって、こちらで学ぶのもお勧めです。
3–3: 画面遷移とウィジェットの状態管理
この内容 + αな感じでした。
3–4: アセット管理とアニメーション
アセットについては、この内容です。
アニメーションは、以下と同様にAnimationControllerを利用するパターンでした。
それも大事ですが、こういった扱いやすいアニメーションWidgetを把握・活用した上で、それで実現できない場合に仕方なくAnimationControllerで明示的に書く、というスタンスが良いと思ってます。
3–5: ウィジェットの応用
パフォーマンス対策などについて述べられています。
p. 131で以下のようなものがWidgetのネスト構造と記載されていますが、
パフォーマンス観点での言及としてはこれは誤解を招きかねない表現で、上の単純なものでも実際には以下のようなかなり巨大なツリーとなっています。
通常のデバッグ実行では、アプリコードとして書いたWidgetのみが表示対象となっていてコンパクトに見えますが、 — no-track-widget-creationオプション付きで起動すると2枚目のような実際の巨大なツリーを確認することができます。Track widget creation にも書いてある内容です。
(書籍でもp.234あたりにこのあたり把握しているであろう記載もありますが。)
ちなみに、このような巨大なWidgetツリーであっても、Widgetは軽量な設計図であり描画ツリーではないので、これ自体がパフォーマンス的に大きな問題になりにくいです(書籍でも触れているように、上位ツリーへO(1)のアクセスするなど、ベストプラクティスに沿って書いた場合)。とはいえ程度問題であり、富豪的に大きなWidgetツリーをリビルドしているとパフォーマンス劣化に繋がり得るのと、もしそれが問題なくともバッテリー持ちなどにも関係してくるので、無駄なリビルドは控えめにするに越したことない、程度の感覚で良い気がしています。
また、例えば次のように見た目はすっきりしててもリビルド負荷が高いコードは簡単に書けてしまうので、buildコードに記述しているWidgetの深さと幅をそのままパフォーマンスに結びつけて考えるのは違和感があります。実際、本のコード例の無駄なリビルドは構造そのままで const
付けるだけでもかなり解消します。
class MyPage extends StatefulWidget {
const MyPage({Key key}) : super(key: key);
@override
_MyPageState createState() => _MyPageState();
}class _MyPageState extends State<MyPage> {
@override
Widget build(BuildContext context) {
return Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () => setState(() {}),
),
// const指定してないので毎回リビルド
body: BigWidget(),
);
}
}
きちんと const
指定するなどお行儀よく書いていれば、 build
メソッドが多少膨らんでも無駄なリビルドは起こりにくく、 build
メソッドの肥大化はどちらかというと可読性・メンテナンス性の観点からコンパクトに抑えるべきだと考えています。
誤植メモ:
・p.57:textDecoration
となっているのはtextDirection
の誤りに見える
・p.106: 「継承しているしている」となっている
・p.112:AnimationBuilder
はAnimatedBuilder
の誤りに見える
Chapter4: 状態管理
宣言的UIであるFlutterでの状態管理の概要と具体的な手法が示されています。ドキュメントの以下に相当します。
本では以下が紹介されています。
個人的には、まずはproviderパッケージ + ChangeNotifierなどでScoped Modelチックに書くのがお勧めだと思っていて、ドキュメントのこの例もそうなっています。一見シンプルな構成ですが、きちんと使いこなせれば、複雑・大規模なアプリにも耐えられます(モデル層での工夫など必要になってきますが)。
ちなみに、Scoped Modelのパッケージはこれから新たに選択するのは微妙だという認識です。
Chapter 5: ライブラリの実装
ドキュメントの以下に相当する内容です。Dart/Flutterのパッケージの作成・配布周りはかなり使いやすく整備されていて快適ですね。
誤植メモ
・p.170: 「pubspec file」/「pubspec.yamlファイル」、「lib directory」/「libディレクトリ」の表記揺れ
Chapter 6: サンプルアプリの実装
バックエンドはFirebase、状態管理はBLoCパターンで組んだ小さめのサンプルアプリの解説です。GitHubにリポジトリがあるようですが、そのURLの記載が見当たらずどこか分からなかったです🤔
また、せっかくBlocProviderにも触れているのに、最後に出てくる SignInScreen
の build
メソッドで毎回BLoCオブジェクトを初期化するというアンチパターンになっているのも気になりました。サンプルではたまたまうまく動いているかもしれませんが、実際のアプリでやると挙動不審になったり無駄な処理が何回も呼ばれたり悪影響を及ぼします。
BLoCオブジェクトは基本的に状態を持つので、StatefulWidgetのStateで保持するか、それをラップしたBlocProviderなどのbuilderで生成して寿命を長くするのがセオリーです。
誤植メモ
・p.205:null`
となっていて、`
が混入している
・p.206: equatableパッケージが0.5以前のもので、9月にリリースされた0.6以降と書き方が違う(誤植じゃないものの読者が戸惑いそうなので一応)
Chapter 7: 開発の継続
7–1: テストと最適化
前半は、以下のツールなどを使いこなすと、開発の効率化・パフォーマンス最適化などができる、という内容です。
後半はテストで、以下について説明されています。
- Unitテスト
- ウィジェットテスト
- Integrationテスト
ウィジェットテストは、一般的な単体テストとUIテストの中間のようなもので特定のWidgetの振る舞いを高速にテストできて便利です。いわゆるUIテストほど対応コストがかからずに済みます。
Integrationテストは、実際にアプリを起動するテストで、一般的なUIテストに相当します。ネイティブプラグインにはこのテストが必要で、FlutterFire(iOS/Android向けのFirebaseプラグイン) などで積極的に使われています。
僕も以前、 firebase_storage のバグ修正をした時にこのIntegrationテストコードを弄りました。
7–2: デプロイメント
以下に相当する内容でした。
CI/CDサービスでは、CodemagicとBitriseが紹介されていました。
最近は、8月にリニューアルしてアプリのビルドなども可能となったGitHub Actionsを利用しているケースもよく見受けられます。
誤植メモ
・本の表紙に「ログ」というトピックが載っているのに、p.241でDevToolsのログ画面に触れている程度しか言及なくて違和感あり。
・p.268:CodeMagic
ではなくCodemagic
です。
付録
Flutter 1.9
9月にstable channelにリリースされた1.9の紹介です。
個人的に最近仕事でFlutterでのWebアプリに取り組んでいますが、かなり好印象です。
(Web対応はまだテクニカルプレビューなので、きちんと検証・リスク判断をしてから自己責任で使う必要があります。)
まだWeb対応のパッケージが少ないので、ネイティブアプリとの実装共通化したい場合は自分でそのパッケージなど書く必要があったりしますが、そのあたりが成熟してくるのが楽しみです。
Dart言語
以下に相当する内容でした。
Dartにも、DartPad埋め込みで実行・編集できるCodelabが用意されているので、そちらを使って学習するのもお勧めです。
以上、本を読みながら感想や補足など記しました。
所感
2019年10月発売にも関わらず、9月時点での内容となっていて進化の速いFlutterの最新状況が日本語で体系的に掴める本だなと思いました。一方、Flutter/Dartのドキュメントが極めてよくできていて動画・ブログなどでの情報発信も盛んなため、英語の読み聴きができればそちらで十分な気もしてしまいました。逆に言うと、とりあえず日本語で一通りインプットしたい場合には適した本だと思います。
ネットでの情報は書籍よりも表現力が高いですし、もちろん特に公式情報は常に最新なので、Flutterのように進化の速い技術を追うにはやはり公式情報・海外ブログなどもスラスラ吸収できる英語力があった方が有利だと改めて思いました。
いくつか気になる点はありつつも、全体的に良い本だと思いました。今の職場でもFlutterの流れがきているので、この本をお勧めしようと思います🐶