Flutterで本格的にアプリを書き始める前にやること
Flutterでアプリ開発を始める前に個人的にやっていることをまとめてみる。個々の作業の具体的な手順や方法に関しては分量が膨大になってしまうので触れないが、より詳しく解説してくれている記事やドキュメントへのリンクなんかは載せておこうと思う。複数人で開発する場合は証明書周りなんかはもっと考慮すべきことはあると思うのだけど今回は省く。
環境設定
version
新規アプリならFlutterのversionは2系からでいいと思う。1系で書く理由として一部のパッケージで2系対応してないなどはあるが、主要なパッケージはほぼ全て問題なく対応してるはずなので2系を使えば良い。
null safety
null safetyを後から入れる、もしくは移行でnull safety対応するのは結構骨の折れる作業なので最初から有効にしておくべき。上述したようにFlutterの2系を使っていればnull safetyがデフォルトになってたはず。
build設定とflavorの設定
まずはbuild設定とflavorの設定をする。実務では例えば、release
ビルドで環境はstaging
みたいなビルドを作りたくなることがよくある。これをするためにはbuild設定とflavor設定によってアプリを切り替えられるようにしておくと良い。具体的には下記のようなコマンドでアプリを実行できるようにする感じのイメージ。
$ flutter run --release --flavor staging
これにはiOS/Androidでそれぞれ別途準備が必要になる。下記のQiitaとmonoさんの記事がわかりやすく解説されているのでよく読む。
- flutterで本番/ステージング/開発を切り替える - Qiita
- Flutterで環境ごとにビルド設定を切り替える — iOS編. モバイルアプリ開発において、環境ごとに設定を変えてビルド・配信することはほぼ必須… | by mono | Flutter 🇯🇵 | Medium
v1.17から利用できるDart-define
を利用して本番/ステージング/開発の環境を切り替える方法もある。それについては下記の記事を参考に行う。
[iOS]Provisioning Profile(dev/AdHoc/AppStore)の用意と[Android]keytoolで証明書の作成
割愛。手動でやるなり自動化するなりご自由に。
アイコンを環境ごとに分ける
環境ごとにアプリアイコンを分けておくと端末にインストールされた時視認性が上がるのでやっておくとよい。flutter_launcher_iconsを使うとすぐできる。アイコンがまだ用意出来てない場合でも、自分はこんな感じの色付けをした雑なアイコンで分けてる。
Lint/Analyzerの設定
プロジェクトのルートにanalysis_options.yaml
を設置する。新規プロジェクトなら最初から厳し目の規約を導入した方が良い。pedantic_mono+カスタムルールが結構良い感じ。
加えてGitHub ActionsでPRをフックにAnalyzerとformattingを実行させてチェックする設定をしておくのも良い。無駄なレビュー時の指摘とかが減る。
subosito/flutter-actionを使って.github/workflows
配下に下記のようなyamlを置いておくだけ。
name: Flutter_Analyzer_Formatter
on:
pull_request:
branches: [main]
jobs:
flutter_analyze:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v2
with:
fetch-depth: 1
- uses: subosito/flutter-action@v1
with:
flutter-version: "1.22.5" <- ここは使用してるFlutterのversionを指定。
- run: flutter pub get
- run: flutter analyze
// 特定のファイルだけ省いたりできないので./のところを./dir1 ./dir2 ./dir2 ...みたいな感じで直接指定すれば良い
- run: dart format ./ --set-exit-if-changed
CI/CD設定
初期の段階でCI/CDの設定をしておくと良い。あとからだと依存関係の解決とかビルド時間がかかる等で面倒になってしまう。場合によってはpublishの設定までしなくていいからとりあえずリポジトリにpushしたらテストが走りビルドが作成される、くらいはiOS/Android両方やっておくべき。CIサービスとしてはCodemagicはGUIから設定出来るし簡単なのでおすすめ。
Firebase全般
最近は何はともあれFirebaseを使うことも多いと思うので設定しておく。すでに開発/ステージング/本番と環境をflavorで分割できるようにしているはずなので、それに合わせてそれぞれの環境ごとのFirebase Projectを作る。次にgoogle-services.jsonやGoogleService-Info.plistといったFirebaseの設定ファイルをflavorごとに分けて使用できるようにする。初めての人は少し複雑で迷うかもしれないが下記の記事などを頼りにやっていく。
- Flutter アプリに Firebase を追加する
- flutter + firebaseで本番環境と開発環境を切り替える - Qiita
- Flutter Flavor— Multiple Environment setup with Firebase | by Ashok Kumar | Medium
Firebase Functionsの準備
大抵の場合Firebaseを使うときはFunctionsやFirestoreを使う気がするのでスタートガイドのProjectの初期化あたりまではやっておくと良い。Firestoreのruleやindexの雛形やfunctionsのブートストラッピングができる。
あとはFunctionsのデプロイ時のソースコードのアーカイブの削除設定とかもやっておくと良さそう
よく利用しそうなライブラリの準備
Firebase系
色々あるが自分は下記のサービスをよく利用してるのでデフォルトでいれる。その他にもFunctionsやらMessagingやら沢山あるので公式ページを読むと良い。
- Firestore
- Firebase Authentication
- Analytics
- Remote Config
監視&エラートラッキング
設定が手軽で導入も無料なのでとりあえず入れておく。
状態管理
- provider + change_notifier
- riverpod + freezed + state_notifier
- flutter_bloc
- pure bloc + rxdart
- Redux
等々好みと規模に合わせて好きな組み合わせを選ぶ。日本だとmonoさんを中心にriverpod + freezed + state_notifierの組み合わせが流行りそうな雰囲気がある。自分は実務で長いことBLoCを中心に使ってきたのとRails方面で育ったところがあるので規約に縛られるような記述がむしろ好きで、flutter_blocあたりは手に馴染む。コードジェネレータに慣れてないというのもある。この辺は完全に好み。
HTTP
ローカルデータ
もっと高速なhiveみたいなのもあるけど公式だし手軽だしというところでとりあえずshared_preferencesを使うことが多い。
- shared_preferences
テスト
- Mockito
多言語化
後からでもいいけど一箇所ずつ置換していくのも面倒になるし最初からやっておくと良い。下記の公式Docsとmonoさん記事などを読んでやる。
- Internationalizing Flutter apps - Flutter
- Dart/Flutter での多言語対応あれこれ. 公式ドキュメントだけでは分かりにくいところを詳細解説 | by mono | Flutter 🇯🇵 | Medium
ディレクトリ構成を決める
lib配下のディレクトリ構成については議論が多々あると思うが自分は最初はこんな感じで始めることが多い。
.
├── app.dart
├── main.dart
├── constants.dart
├── blocs
│ ├── README.md
│ └── blocs.dart
├── l10n
│ ├── delegate.dart
│ ├── localized.dart
│ ├── message.dart
│ ├── messages_all.dart
│ ├── messages_en.dart
│ └── messages_ja.dart
├── models
│ ├── README.md
│ └── models.dart
├── repositories
│ ├── README.md
│ └── repositories.dart
├── screens
│ ├── README.md
│ └── example_screen.dart
├── utils
│ ├── error_logger.dart
│ └── my_config.dart
└── widgets
└── README.md
flutter_blocを使う場合なのでblocディレクトリがあるけど、他の状態管理を採用しても似たような感じにはできるはず。APIとかFirestoreなどのデータソースは状況に応じてrepositories内に掘っていったり別ディレクトリを作るかもしれない。l10nに関しては多言語対応のファイル置き場。あと各ディレクトリにREADME.mdを置いてるのはそのディレクトリに配置するファイル名の規約とかそのファイルに書くクラスの書き方の例などを書いて他の人がコードを読むときの助けになればよいなと思っておいてある。もっときっちり責務分割していくのが好きな人には微妙〜〜という感じかもしれないがあくまで一例ということで...。
この辺のディレクトリ構成とかライブラリとかアーキテクチャに関しては@wasabeef_jpさんの下記のリポジトリが参考になりまくるので読んで!!
終わりに
ざっと書いてはみたが、とりあえずmonoさんに足を向けて寝れねぇなということがわかった...😇。
他にもテーマの設定とか事前にやっておいた方がいいことは色々ある気がするし挙げればキリがない。ただ大事なのはそのプロジェクトの用件やチームの規模感や習熟度の考慮である。場合によってはここにあるもの全てをやる必要はないし、実はもっと事前にやらないといけないことがあるかもしれない。これらはあくまでも自分の場合の例、ということでその辺はご容赦くださいと言い訳して終わりにします。
文句は@razokuloverへ。
Discussion