はじめに
Flutterでの環境切り替えには色々方法がありますが今回は--dart-define
でビルド時にパラメーターを渡して接続を切り替えるシンプルな実装でやってみようと思います
Flavor等のパッケージを使用する場合に比べ、設定や新規で作成するファイルが少なくなるため(多分)
小さいアプリなら簡単に対応できるというメリットがあるかなという所感
目次
実装後のイメージ
起動時のファーストビューで接続先(url文字列)が画面に表示されているようにして
環境の切り替えができている確認とします
本来は開発環境、テスト環境、本番環境ぐらいには分けたいですが、
今回は簡単に開発環境(dev)本番環境(prod)の二つで試してみます
以下のようなコマンドで起動、環境の切り替えができるようにします
flutter run --dart-define=FLAVOR=dev
Flutter側の実装
環境の定義
flutter_dotenvを使用して
各環境の接続先を環境変数として定義します
# dev(開発)環境
DEFINE_DEV_BASE_URL='http://development.api.qiita.demo/api'
# production(本番)環境
DEFINE_PROD_BASE_URL='http://production.api.qiita.demo/api'
pubspec.yamlに.envファイルを記載してflutter側でファイルを読み込めるようにします
assets:
- .env
環境を切り替えるロジックを実装
String.fromEnvironment('FLAVOR');
の箇所で--dart-define
で指定した
文字列を取得
取得した文字列ごとに分岐し、異なる環境変数を格納しているのでソースは後述しますがflutter側からはenvironment['baseUrl']
でアクセスすることができます
import 'package:flutter_dotenv/flutter_dotenv.dart';
const String flavor = String.fromEnvironment('FLAVOR');
final variablesDev = {
'baseUrl': dotenv.env['DEFINE_DEV_BASE_URL'],
};
final variablesProd = {
'baseUrl': dotenv.env['DEFINE_PROD_BASE_URL'],
};
Map<String, dynamic> get environment {
if (flavor == 'dev') {
return variablesDev;
}
if (flavor == 'prod') {
return variablesProd;
}
throw UnimplementedError('baseUrl: $flavor is unknown value');
}
接続先のURLを取得する
environment['baseUrl']
で接続先のURLを取得
import 'package:api_env_demo/api_environment.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
void main() async {
// .envファイルを読み込む
await dotenv.load(fileName: '.env');
// ...runapp
}
// ~~~~~~省略~~~~~
@override
Widget build(BuildContext context) {
// 接続先のURLを取得する
final String path = environment['baseUrl'].toString();
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(path,
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 30),)
],
),
),
);
}
動作確認
以下のコマンドで実行
dev(開発)環境の場合
flutter run --dart-define=FLAVOR=dev
prod(本番)環境の場合
flutter run --dart-define=FLAVOR=prod
--dart-define
で指定した環境のURLを正常に取得できていそうです
デバッグする時
実際にローカルで開発している時デバッグしたりすると思うのですが
その時の設定に関してです
VSCodeでの設定の例を記載
launch.jsonの設定を以下のように記載
{
"version": "0.2.0",
"configurations": [
{
"name": "api_env_demo_dev",
"cwd": "api_env_demo",
"request": "launch",
"type": "dart",
"flutterMode": "debug",
"args": [
"--dart-define=FLAVOR=dev",
]
},
{
"name": "api_env_demo_prod",
"cwd": "api_env_demo",
"request": "launch",
"type": "dart",
"flutterMode": "debug",
"args": [
"--dart-define=FLAVOR=prod",
]
},
]
}
リリース時のコマンド
リリースの時でも同じようにビルドコマンドに--dart-define
のオプションを指定するだけで任意の環境で配布することができます
例)iOS
flutter build ipa --dart-define=FLAVOR=dev --export-options-plist=ios/ExportOptions.plist
ローカルでのビルドと違い、iOSやAndroid等のプラットフォーム側にオプションを伝える必要があるので別途設定が必要になってきます
この辺の詳細に関しては以下の記事がすごく参考になりました
【Flutter 3.7以上】Dart-define-from-fileを使って開発環境と本番環境を分ける
最後に
リリース時のアイコンや名前も環境ごとに切り替えることを考えると他に最適なやり方があるのかなと思いつつも
現状問題がないのでこのような感じで環境を切り替えて日々開発しています
今後もっといい方法を見つけたら書いてみたいと思います