Flutterを0から学び、76日でAndroid, iOSのアプリをリリースした裏話
はじめまして、note初投稿になります。
Kaoru(@mcz9mm)です。普段はネイティブでの開発をメインにエンジニアとヒカセンをしています。
自身初となるクロスネイティブでの開発ということでFlutterにチャレンジしてみました。学びの過程からリリースまでの道のりをざっくりとではありますがまとめていければと思います。
今回リリースしたサービスについて
タラレバ貯金という日々の「したつもり、 食べたつもりでガマン」を応援するアプリをリリースしました🚀
ランチやスナック、ドリンクなどの毎日何気なく浪費している分を節約し、買ったことにして貯金するアプリです。家計簿とは違い、目標に大してどれだけ貯めたかを記録できるものになってます。
最初はUdemyでインプット
最初はUdemyで動画を観ながら勉強を始めました。Flutterで利用するDart言語はもちろん始め方すら分からない時点でのスタートでした。動画なので自分のペースで理解できるまで繰り返し確認できるのも良いです。
内容は全て英語ですが非常にゆっくりで聞き取りやすく、最悪翻訳ツールを使えば問題なく理解できるものになっています。
環境構築からデータ通信、Firebaseでの連携、基本的なことは大体教えてくれます。Flutter初学者の私にとって、非常に価値のある内容でした。
※受講した講座の詳細はこちら
学びやメモは全てアウトプット
TIL(Today I Learned)形式でその日の学んだことを毎日記事として書き上げることを続けました。GitHub上にも公開してます(こちら)
TIL自体はインプットの多かった最初の1ヶ月、ほぼ毎日書き上げました。途中で開発を優先させるために記事は書いていませんでしたが、お世話になった記事などは必ず保存しています。
書いた記事、結果的に自分で見返すことが多く非常に助かりました🙏
特に動きのあるものはGIFにしてメモ・アウトプットをすると、実装を見て思い出すよりも遥かに効率的でした。
Flutterについて
最初から最後まで感じていたことは、「コミュニティが栄えており公式ドキュメントが分かりやすい」ということです。
公式ドキュメントを見れば大体解決できますしFlutterのリポジトリではissueでのやりとりが盛んに行われています。
両OSネイティブを触っている立場として感じたのはレイアウト実装のスピードですね。Hot reloadの機能があるので、UIの構築、機能の追加、バグの修正が比較的容易に行うことができます。
複数画面で共通部分のUIが絡んだ実装が非常にしやすかったです。
コンポーネントとしてパーツを切り出しておけばどこでも簡単に利用できるのは便利ですね。
※実際のアプリのとある画面のレイアウト情報。merginやpadding等も視覚的にチェックできます。
また、開発して感じたFlutterの魅力として挙げられるのがpackageの利用のしやすさです。100点満点でスコアリングされ、健全なコードか、メンテナンスされているか、人気かどうかなど加味された情報が見れるので採用するかどうかまで手軽に行うことができます。(iOSの場合、私がやっていたのは誰かがまとめてくれた記事やGitHubのリポジトリを見て探していました)
実際にレイアウトやUI実装をしてみて
Flutter Galleryなどを参考にしました。また、サンプルアプリ等も公開されており、ネイティブよりも楽に実装まで進めることができます。
Flutter inspector
私がそうだったんですが、Flutterと聞いた時の印象は「Widgetのネストが、、、」ということが一番でした。しかも見た目の実装が全てコードオンリーなんて、Storyboard信者からすると苦手意識を感じずにはいられません。。。
Flutter inspectorはウィジェットツリーを視覚化したり、選択したパーツがどのWidgetになのか確認することもできます。ネイティブ環境にあったStoryboardやXMLなどと変わらず、もしくはそれ以上(Hot reloadもあったこともあり)だったと思います。
ダークモード対応について
Themeがあるので実装時間としては1~2時間ほどで全画面対応ができたかと思います。こちらの記事を参考にさせていただきました。@itometeamさん、Theme以外にも非常に参考になりました。ありがとうございます!
child: MaterialApp(
theme: ThemeData.light(),
darkTheme: ThemeData.dark(),
home: SplashPage(),
),
基本はこれだけ。あとは気になるパーツごとに個別でカラーを当てれば問題ないです。
Theme.of(context).scaffoldBackgroundColor
ダークモードや通常(ライト)時の判定
var brightness = MediaQuery.of(context).platformBrightness;
color: (brightness == Brightness.light) ? kBackgroundListColor : Theme.of(context).scaffoldBackgroundColor,
OSの判定
import 'dart:io';
Platform.isIOS // bool
Platform.isAndroid
他にもisMacOSやisWindows, isLinuxなど細かい判定も可能です。
アプリ内の設定情報の保持
shared preferencesを使って設定内容系は保存してます。iOSで言うとUserDefaultsです。key valueで保存できますが、保存できる型が
bool, int, double, String, List<String> なので注意です。
貯金の記録や目標のデータはSQLiteで保持
今回はデータの保存をSQLiteで行っています。使い方含めて下記2つのサイトが参考になりました。SQLインジェクションだけ注意です。
iOSリリース申請について
こちらも公式ドキュメントがあるので参考にしていただければ。基本的にネイティブと同様なので困った箇所は無かったです。強いて言えば、アイコンやスプラッシュ画面は各自で設定しないといけないので注意ですね。
Androidリリース申請について
ネイティブの方でも1度経験があるので余裕かと思ってましたがGoogle Play App Signingでの署名系にちょっと時間とられてしまいました。
下の公式ドキュメントを読み進めるだけでうまくいったので参考にしてみてください。
特にkeystoreの設定からアプリの書き出しまでコマンドや手順が記されているのは助かりますね。
デザインについて
アプリ内の素材はFlutterのIconsのclassを利用しました。こだわり等なければこれで事足りると思います。
アプリのアイコンとスクリーンショットはSketchで作成してますがこれはFlutter関係なく必要ですね。
今後について
リリース後は改善のための開発を引き続き行っていくつもりです。貯金アプリ系は非常にたくさんあるので差別化を図りつつ使いやすいものにしていきます。
もし気に入ってくれれば、インストールして使ってみてください。アプリをTwitterなどSNSでシェアいただけるとめっちゃ喜びます😻
インストールはこちら
iOS
Android