4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Flutter】--dart-defineを使用して環境ごとにAPIの接続先を切り替える

Last updated at Posted at 2023-03-30

はじめに

Flutterでの環境切り替えには色々方法がありますが今回は--dart-defineでビルド時にパラメーターを渡して接続を切り替えるシンプルな実装でやってみようと思います

Flavor等のパッケージを使用する場合に比べ、設定や新規で作成するファイルが少なくなるため(多分)
小さいアプリなら簡単に対応できるというメリットがあるかなという所感

目次

  1. 実装後のイメージ
  2. Flutter側の実装
  3. 動作確認
  4. リリース時のコマンド
  5. 最後に
  6. 参考文献

実装後のイメージ

起動時のファーストビューで接続先(url文字列)が画面に表示されているようにして
環境の切り替えができている確認とします
本来は開発環境、テスト環境、本番環境ぐらいには分けたいですが、
今回は簡単に開発環境(dev)本番環境(prod)の二つで試してみます

以下のようなコマンドで起動、環境の切り替えができるようにします
flutter run --dart-define=FLAVOR=dev

Flutter側の実装

環境の定義

flutter_dotenvを使用して
各環境の接続先を環境変数として定義します

.env
# 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側でファイルを読み込めるようにします

pubspec.yaml
assets:
    - .env

環境を切り替えるロジックを実装

String.fromEnvironment('FLAVOR');の箇所で--dart-defineで指定した
文字列を取得
取得した文字列ごとに分岐し、異なる環境変数を格納しているのでソースは後述しますがflutter側からはenvironment['baseUrl']でアクセスすることができます

api_environment.dart
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を取得

main.dart
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の設定を以下のように記載

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を使って開発環境と本番環境を分ける

最後に

リリース時のアイコンや名前も環境ごとに切り替えることを考えると他に最適なやり方があるのかなと思いつつも
現状問題がないのでこのような感じで環境を切り替えて日々開発しています
今後もっといい方法を見つけたら書いてみたいと思います

参考文献

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?