menu事業部 フロントエンドエンジニアの坂井田です。
業務で開発する際、開発環境と本番環境を分けたいという場面があるのではないでしょうか。
今回は、それをFlutterで実現する方法についてご紹介します!
- 環境(Flavor)ごとに設定を分ける方法
- はじめに:Flavorを用意する
- 便利な設定:VSCodeでデバッグするFlavorを選択できるようにする
- 1️⃣ アイコンをFlavorごとに変える
- 🍏 Android
- 🍎 iOS
- 2️⃣ ホーム画面に表示される名前をFlavorごとに分ける
- 3️⃣ 別アプリとしてインストールできるようにする
- ビルドしてみる
- アプリ内でFlavorを判別する
- 最後に
環境(Flavor)ごとに設定を分ける方法
ズバリ、dart-define-from-file というオプションを使用することで簡単に実現できます!
dart-define-from-file
は Flutter 3.7 (2023/1/25 リリース) から利用可能になった機能で、ビルド時に指定したjsonファイルを使って各種設定を切り替えてビルドすることができます。
この記事では、以下を実現するために必要な設定について説明します。
- 1️⃣ アイコンをFlavorごとに分ける
- 2️⃣ ホーム画面に表示される名前をFlavorごとに分ける
- 3️⃣ 別アプリとしてインストールできるようにする
はじめに:Flavorを用意する
dart_defines
ディレクトリを作成し、その中に以下2つのファイルを作り渡したい値を記述します。
ここでは、アプリ名・アイコン・別アプリとしてインストールするための設定を記述しています。
stg.json
{ "flavor": "stg", "appName": "(stg) FlavorSplit", "appIdSuffix": ".stg" }
prod.json
{ "flavor": "prod", "appName": "FlavorSplit", "appIdSuffix": "" }
こうすることで、ビルド時にオプションで指定すると各jsonをもとに設定を切り替えることができるようになります。
STG環境でapkをビルドする例:flutter build apk --dart-define-from-file=dart_defines/stg.json
便利な設定:VSCodeでデバッグするFlavorを選択できるようにする
.vscode/launch.json
の configurations
に選択肢の設定を記述します。
それぞれ args
の部分で dart-define-from-file
のオプションを指定してください。
{ "version": "0.2.0", "configurations": [ { "name": "Debug dev", "request": "launch", "type": "dart", "flutterMode": "debug", "preLaunchTask": "create_env_dev", "args": [ "--dart-define-from-file=dart_defines/dev.json", ] }, { "name": "Debug stg", "request": "launch", "type": "dart", "flutterMode": "debug", "preLaunchTask": "create_env_stg", "args": [ "--dart-define-from-file=dart_defines/stg.json", ] }, { "name": "Debug prod", "request": "launch", "type": "dart", "flutterMode": "debug", "preLaunchTask": "create_env_prod", "args": [ "--dart-define-from-file=dart_defines/prod.json", ] }, ] }
1️⃣ アイコンをFlavorごとに変える
各OSごとに必要なサイズのアイコンを自動生成してくれるパッケージ flutter_launcher_icons
を利用すると便利です。
以下のような各Flavorのアイコンを用意し、assets/launcher_icon
内に配置します。
icon-stg.png |
icon-prod.png |
---|---|
次に自動生成の設定ファイルを作成します。
flutter_launcher_icons-stg.yaml
flutter_icons: android: true ios: true image_path: "assets/launcher_icon/icon-stg.png"
flutter_launcher_icons-prod.yaml
flutter_icons: android: true ios: true image_path: "assets/launcher_icon/icon-prod.png"
pubspec.yaml
に以下の記述を追加します。
flutter_icons: android: true ios: true
あとは以下のコマンドを実行すると、設定に沿って必要なアイコンを自動生成できます。
flutter pub run flutter_launcher_icons:main
ただ、これだけでは各Flavorのアイコンが適用されないため、OSごとにネイティブの設定を変更する必要があります。
🍏 Android
android/app/build.gradle
の最後に以下のコードを追加します。
task copySources(type: Copy) { from "src/$flavor/res" into 'src/main/res' } tasks.whenTaskAdded { task -> task.dependsOn copySources }
🍎 iOS
ios/Runner.xcodeproj/project.pbxproj
にあるASSETCATALOG_COMPILER_APPICON_NAME
の記述をすべて以下のように変更します。
ASSETCATALOG_COMPILER_APPICON_NAME = "AppIcon-$(flavor)";
2️⃣ ホーム画面に表示される名前をFlavorごとに分ける
jsonで設定したアプリ名になるようにします。
🍏 Android
android/app/build.gradle
にある defaultConfig
の中に、以下の記述を追加します。
resValue "string", "app_name", appName
また、android/app/src/main/AndroidManifest.xml
にある label
を以下のように変更します。
android:label="@string/app_name"
🍎 iOS
ios/Runner/Info.plist
にある CFBundleName
と CFBundleDisplayName
のstringを、以下のように変更します。
<string>$(appName)</string>
3️⃣ 別アプリとしてインストールできるようにする
Androidでいうパッケージ名、iOSでいうバンドルIDをFlavorごとに変更することで、一つの端末に別アプリとしてインストールできるようになります。
Androidのアイコンの周りに余白がありますが、これについては別の記事で説明します。
🍏 Android
android/app/build.gradle
にある defaultConfig
の中に、以下の記述を追加します。
applicationIdSuffix appIdSuffix
🍎 iOS
ios/Runner.xcodeproj/project.pbxproj
にある PRODUCT_BUNDLE_IDENTIFIER
の部分を以下のように変更します。
※RunnerTests
の行はそのままにする
PRODUCT_BUNDLE_IDENTIFIER = "<元々のバンドルID>$(appIdSuffix)";
これで、主要3点の設定は完了です。
ビルドしてみる
いつものビルドコマンドに、オプションとして dart-define-from-file
とビルドに使用するjsonファイルのパスを書くことでビルドすることができます。
例えば、STG環境のAndroidアプリをビルドする場合は以下のコマンドになります。
flutter build apk --dart-define-from-file=dart_defines/stg.json
必要に応じてMakefileを作ると便利かもしれません。
build-android: flutter build apk --dart-define-from-file=dart_defines/$(flavor).json
上記Makefileを作成すると、以下のコマンドでビルドできるようになります。
make build-android flavor=stg
あとは、dart-define-from-file
で設定した値をアプリ内で受け取る方法について説明します。
アプリ内でFlavorを判別する
やり方は簡単で、String.fromEnvironment('<設定した値のキー>')
と書くだけで取得できます。
例えば、Flavor名を取得したい場合は以下のように記述します。
const flavorName = String.fromEnvironment('flavor');
これを表示してみると、Flavorごとに異なる値が表示されることを確認できます。
STG | 商用 |
---|---|
最後に
いかがでしょうか。
この他にも任意の値をビルドごとに分けることができるので、必要に応じて値を追加してみてください。