Flutter で環境ごとにビルド設定を切り替えるためには、Flavor を設定する必要があります。
Creating flavors for Flutter - Flutter
ですが調べてみると、Flavor を設定するためには各 OS ごとに手動でそれぞれ設定しなければならないため面倒です。
- 【Flutter】Flavor の設定~build まで(Android 編) - Qiita
- Flutter で環境ごとにビルド設定を切り替える — iOS 編. モバイルアプリ開発において、環境ごとに設定を変えてビルド・配信することはほぼ必須… | by mono | Flutter 🇯🇵 | Medium
もっと楽して Flavor を設定できないかさらに調べてみたところ、下記のパッケージを使えば実現できるようでした。
そこで、この 2 つのパッケージを使って Flavor を設定する方法をまとめます。
各パッケージのインストール
pubspec.yaml
に下記の通り記載します。
dependencies:
flutter_flavor: ^1.1.3
flutter_flavorizr: ^1.0.9
その後、flutter pub get
コマンドを実行します。
flutter_flavorizr
flutter_flavorizr
とは、各 OS ごとの Flavor の設定を一括管理してくれるパッケージです。そのため、各 OS ごとに手動でそれぞれ設定しなければならない手間を解消してくれます。
flutter_flavorizr
を使うための準備
flutter_flavorizr
を使うためには、事前に下記の 3 つを準備する必要があります。
Mac の場合、すでにRuby
とGem
がインストールされていることがありますが、権限の問題上gem install
が使えません。
そのためRuby
とGem
をインストールするにあたり、rbenv
を使ってインストールするのがおすすめです。
インストール方法は下記が参考になりました。
gem install で permission エラーになった時の対応方法 - Qiita
Flavor の設定
Flavor を設定するには、下記のように pubspec.yaml を編集して Flavor を定義する必要があります。
# Flavorの設定
flavorizr:
app:
android:
flavorDimensions: "flavor-type"
ios:
flavors:
local:
app:
name: "アプリ名(local)"
android:
applicationId: "com.example.testapp.local"
ios:
bundleId: "com.example.testapp.local"
dev:
app:
name: "アプリ名(dev)"
android:
applicationId: "com.example.testapp.dev"
ios:
bundleId: "com.example.testapp.dev"
prod:
app:
name: "アプリ名"
android:
applicationId: "com.example.testapp"
ios:
bundleId: "com.example.testapp"
flavorizr
という名前の新しいキーを追加し、app
とflavors
の 2 つのサブアイテムを定義します。
app
配下の下で、各 OS 固有のビルド設定を定義できます。
注意点として、flavorDimensions
は公式だと「required false」と記載がありますが、必ず何かしら記載しないとエラーになります。
特にこだわりがなければ、flavor-type
と記載しておけば問題ありません。
flavors
配列の下で、Flavor の名前を定義できます。
今回の例では local と dev、prod を作成します。
Flavor ごとにアプリ名、アプリケーション ID、バンドル ID を指定する必要があります。
Flavor の設定の反映
Flavor の設定が終了したら、次のコマンドを実行してスクリプトを実行できます。
flutter pub run flutter_flavorizr
スクリプト完了後、Flavor 用の各種コードが自動生成&追記されます。
また、Flavor ごとにmain-xxx.dart
(xxx
には Flavor 名)が自動生成されます。
動作確認
Android または iOS の実機もしくはエミュレータ等を接続し、次のコマンドを実行してアプリを起動できます。
例えば、Flavor をlocal
で起動してみます。
flutter run --flavor local -t lib/main-local.dart
すると、下記のような画面が起動します。
ここで iOS のシミュレータを使って起動しようとすると、下記のエラーが出て起動に失敗する場合があります。
Launching lib/main-local.dart on iPhone 12 Pro Max in debug mode...
Running pod install... 4.3s
Running Xcode build...
Xcode build done. 25.6s
Failed to build iOS app
Error output from Xcode build:
↳
2021-02-14 08:43:14.336 xcodebuild[4440:55848] [MT] PluginLoading: Required plug-in compatibility UUID 2F1A5FFF-BFEB-4498-B2AC-1296A7454F81 for plug-in at path '~/Library/Application Support/Developer/Shared/Xcode/Plug-ins/Unity4XC.xcplugin' not present in DVTPlugInCompatibilityUUIDs
2021-02-14 08:43:14.336 xcodebuild[4440:55848] Failed to load plugin at: /Users/Hitoshi/Library/Application Support/Developer/Shared/Xcode/Plug-ins/Unity4XC.xcplugin, skipping. Reason for failure: *** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[0]
** BUILD FAILED **
Xcode's output:
↳
diff: /Podfile.lock: No such file or directory
diff: /Manifest.lock: No such file or directory
error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.
note: Using new build system
note: Building targets in parallel
note: Planning build
note: Constructing build description
warning: Ignoring destination platform iOS and building against target platform iOS Simulator. If this target is intended to build for only iOS Simulator, configure its Supported Platforms build setting to remove iOS. If this target is intended to build for both iOS and iOS Simulator, set its Base SDK build setting to Latest iOS. (in target 'Toast' from project 'Pods')
warning: The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.4.99. (in target 'Toast' from project 'Pods')
warning: Ignoring destination platform iOS and building against target platform iOS Simulator. If this target is intended to build for only iOS Simulator, configure its Supported Platforms build setting to remove iOS. If this target is intended to build for both iOS and iOS Simulator, set its Base SDK build setting to Latest iOS. (in target 'flutter_secure_storage' from project 'Pods')
warning: The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.4.99. (in target 'flutter_secure_storage' from project 'Pods')
warning: Ignoring destination platform iOS and building against target platform iOS Simulator. If this target is intended to build for only iOS Simulator, configure its Supported Platforms build setting to remove iOS. If this target is intended to build for both iOS and iOS Simulator, set its Base SDK build setting to Latest iOS. (in target 'fluttertoast' from project 'Pods')
warning: The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.4.99. (in target 'fluttertoast' from project 'Pods')
warning: Ignoring destination platform iOS and building against target platform iOS Simulator. If this target is intended to build for only iOS Simulator, configure its Supported Platforms build setting to remove iOS. If this target is intended to build for both iOS and iOS Simulator, set its Base SDK build setting to Latest iOS. (in target 'Pods-Runner' from project 'Pods')
warning: The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.4.99. (in target 'Pods-Runner' from project 'Pods')
warning: Ignoring destination platform iOS and building against target platform iOS Simulator. If this target is intended to build for only iOS Simulator, configure its Supported Platforms build setting to remove iOS. If this target is intended to build for both iOS and iOS Simulator, set its Base SDK build setting to Latest iOS. (in target 'Runner' from project 'Runner')
warning: The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.4.99. (in target 'Runner' from project 'Runner')
warning: Capabilities for Signing & Capabilities may not function correctly because its entitlements use a placeholder team ID. To resolve this, select a development team in the Runner editor. (in target 'Runner' from project 'Runner')
warning: Ignoring destination platform iOS and building against target platform iOS Simulator. If this target is intended to build for only iOS Simulator, configure its Supported Platforms build setting to remove iOS. If this target is intended to build for both iOS and iOS Simulator, set its Base SDK build setting to Latest iOS. (in target 'Flutter' from project 'Pods')
warning: The iOS Simulator deployment target 'IPHONEOS_DEPLOYMENT_TARGET' is set to 8.0, but the range of supported deployment target versions is 9.0 to 14.4.99. (in target 'Flutter' from project 'Pods')
Could not build the application for the simulator.
Error launching application on iPhone 12 Pro Max.
その場合ios/Runner.xcodeproj
を Xcode 側で開き、Update to recommended settings
の警告が出ているはずなので解消してください。
詳細は下記サイトが参考になりました。
Could not build the application for the simulator. Error launching application on iPhone の対応 - Qiita
flutter_flavor
flutter_flavor
とは、各 Flavor ごとでバナーの位置や色を変更したり、変数(API の URL 等)を設定できるライブラリです。
Flavor ごとにリソースを切り替える
例えば local 環境の設定例を下記に示します。
void main() {
FlavorConfig(
name: "LOCAL",
color: Colors.red,
location: BannerLocation.bottomStart,
variables: {
"baseUrl": "https://local-testapp.com/api",
});
F.appFlavor = Flavor.LOCAL;
runApp(App());
}
name
、color
、location
はそれぞれバナーに表示するラベル名、バナーの色、バナーの位置です。
variables
はアプリ内部で使えるグローバル変数です。
ここに API の URL を環境に合わせて設定します。
例えばbaseUrl
を設定することで、下記のように呼び出して使用できます。
// Flavorによって値が変化する
var baseUrl = FlavorConfig.instance.variables["baseUrl"];
また、先程設定したバナーを表示するにはFlavorBanner
を使用します。
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
return (
child: MaterialApp(
title: F.title,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
),
);
}
}
FlavorBanner
を親 ウィジェット、MaterialApp
を子 ウィジェット として設定します。
ここまで出来たら再度ビルドしてアプリを起動すると、下記のような画面が起動します。
まとめ
flutter_flavor + flutter_flavorizr を使って Flutter の Flavor を設定しました。
これらのパッケージを使うことで、各 OS ごとに手動でそれぞれ設定する手間が省けました。
また、pubspec.yaml
で設定を一括管理できるのもメリットだと感じました。
ただ dart コードなどが自動生成されるため、ゴリゴリ実装されている既存プロジェクトへの導入は大変だと感じました。