Flutter の環境分けの新時代
Flutter Advent Calendar 2022 の 5 日目の記事です。
はじめに
みなさん、Flutter の環境分けはどのようにされていますか?
多くの方は、公式で紹介されている flavor を使う方法や --dart-define
を使う方法を使用しているのかなと思います。
今回、紹介するのは Flutter の 3.7.0
で導入された --dart-define-from-file
を使う方法です。
--dart-define-from-file
が導入された背景
--dart-define
を使う方法だと次のような課題がありました。
- 多くの定義がある場合、起動コマンドが非常に長くなってしまう
- 切り替えるパッケージが複数ある場合、保守が困難になる
- これらの定義を Android と iOS で直接利用しようとすると、それぞれで Base64 でデコードしなければならない
これらの課題を解決するために導入されました。
関連する Issue
関連する Pull Request
--dart-define-from-file
の使い方
サンプルプロジェクト
Flutter をインストール
--dart-define-from-file
は、3.7.0
で正式にリリースされた機能です。
そのため、3.7.0
以上のバージョンを使用する必要があります。
次のコマンドを実行します。
# プロジェクトフォルダーを作成して移動
mkdir flutter-mobile-template
cd flutter-mobile-template
# Homebrew をインストール
# https://brew.sh/index_ja
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# FVM をインストール
# https://fvm.app/docs/getting_started/installation
brew tap leoafarias/fvm
brew install fvm
# Flutter をインストール
fvm install 3.7.0
fvm use 3.7.0 --force
fvm flutter --version
# バージョン管理に含めないように .gitignore を作成
echo "flutter_sdk" > .fvm/.gitignore
プロジェクト作成
プロジェクトフォルダーで次のコマンドを実行します。
fvm flutter create \
-t app \
-i swift \
-a kotlin \
--platforms ios,android \
--org dev.blendthink \
--project-name flutter_mobile_template \
.
設定ファイルを作成
それぞれの環境ごとの設定を定義します。
{
"flavor": "dev",
"appName": "dev-Template",
"appId": "dev.blendthink.template",
"appIdSuffix": ".dev"
}
{
"flavor": "stg",
"appName": "stg-Template",
"appId": "dev.blendthink.template",
"appIdSuffix": ".stg"
}
{
"flavor": "prd",
"appName": "Template",
"appId": "dev.blendthink.template",
"appIdSuffix": ""
}
VS Code の設定ファイルを作成
Flutter SDK のパスを設定して、3.7.0
が使用されるようにします。
{
"dart.flutterSdkPath": ".fvm/flutter_sdk",
"search.exclude": {
"**/.fvm": true
},
"files.watcherExclude": {
"**/.fvm": true
}
}
それぞれの環境ごとのデバッグ構成を定義します。
{
"version": "0.2.0",
"configurations": [
{
"type": "dart",
"request": "launch",
"name": "dev-debug",
"args": [
"--dart-define-from-file=flavor/dev.json"
]
},
{
"type": "dart",
"request": "launch",
"name": "stg-debug",
"args": [
"--dart-define-from-file=flavor/stg.json"
]
},
{
"type": "dart",
"request": "launch",
"name": "prd-debug",
"args": [
"--dart-define-from-file=flavor/prd.json"
]
}
]
}
Android の設定
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
@@ -43,14 +47,13 @@ android {
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "dev.blendthink.flutter_mobile_template"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
+ applicationId appId
+ applicationIdSuffix appIdSuffix
minSdkVersion flutter.minSdkVersion
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
+ resValue "string", "app_name", appName
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="dev.blendthink.flutter_mobile_template">
<application
- android:label="flutter_mobile_template"
+ android:label="@string/app_name"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
iOS の設定
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
- <string>Flutter Mobile Template</string>
+ <string>$(appName)</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
@@ -365,7 +365,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- PRODUCT_BUNDLE_IDENTIFIER = dev.blendthink.flutterMobileTemplate;
+ PRODUCT_BUNDLE_IDENTIFIER = "$(appId)$(appIdSuffix)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
@@ -494,7 +494,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- PRODUCT_BUNDLE_IDENTIFIER = dev.blendthink.flutterMobileTemplate;
+ PRODUCT_BUNDLE_IDENTIFIER = "$(appId)$(appIdSuffix)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@@ -517,7 +517,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- PRODUCT_BUNDLE_IDENTIFIER = dev.blendthink.flutterMobileTemplate;
+ PRODUCT_BUNDLE_IDENTIFIER = "$(appId)$(appIdSuffix)";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
アプリ実行
VS Code の Run and Debug
から実行します。
ぱっと見では確認しづらいため、サンプルプロジェクトでは次のステキなパッケージを利用させていただきました✨
サンプルプロジェクトで確認したところ、次のようにログが出力されました🎉
flutter: 👻 INFO 2022-12-05 10:23:44.288258 [package:flutter_mobile_template/main.dart 9:10 in main] PackageInfo(appName: dev-Template, buildNumber: 1, packageName: dev.blendthink.template.dev, version: 1.0.0, buildSignature: , installerStore: com.apple.simulator)
おわりに
いかがでしたでしょうか?
個人的には、とてもメリットが多いと感じたため、正式リリースされたらこちらの方法に乗り換えようかなと思いました。
みなさんもぜひお試しください。
おまけ
タイトルは、ベストアーティスト2022に選出された Ado さんの「新時代」からつけました。
個人的にはとても好きな曲で、作業中によくリピート再生して聴いています。
もし良ければ、みなさんもぜひ聴いていただければ幸いです。
Discussion
良記事ありがとうございます!!
分かりやすい記事ありがとうございます!!
個人的に気になったのがjsonファイル内の変数は予約語ではないっぽいので
同じ意味になって、より簡単に記入できる方法が有るかなと思いました!
以下のスクラップにまとめてます!
コメントありがとうございます🥰
ご認識の通りです🙆♂️
Android の Application ID と iOS の Bundle identifier は若干構成の仕方(サフィックスの付け方)が異なったり、Android と iOS で違う ID にしたいケースなどもあったりするため、あえて分けていました。
ただ、この記事のキー名では↑の意図が伝わりづらいと思いましたので、後ほど修正予定です💡
appIdSuffix
を.dev
のようにドットを含めたら同じような指定方法にすることができたので、そのように修正いたしました!ご指摘のおかげで見直す機会ができ、このようにスッキリ書くことができることに気づくことができました。
改めましてありがとうございました 🥰
前回、↑のように言っていましたが、サフィックスが付いているということが伝われば良いかなと思いこのように修正しました(できれば共通の
appId
を使用していることも分かりやすくできれば良いのですが、いい方法が思いつかず、、)↓差分も貼り付けておきます