【Flutter】Flavorの設定~buildまで(Android編)

## はじめに
* 1つのプロジェクト内で複数の環境を動かしたい場合にFlavorを利用すると思います。その設定~buildの指定方法までを書いていきます。

※本記事では、Androidのみの説明をしています。
※iOS側の設定に関しては、本記事の下にある参考文献を見て頂けると理解出来ると思います。

## 手順
Flavorを使った環境分けの手順を書いていきます。

### 1. 作成する環境について
例として、今回は以下の3つの環境を作っていきます。

* develop    → 開発環境
* staging    → ステージング環境
* production → 商用環境

### 2. まずbuild.gradleにFlavorの設定を追記
* android/app/build.gradleの`android{}`内に以下を追記していきます。

```android/app/build.gradle
    flavorDimensions "flavor-type"

    productFlavors {
        develop {
            dimension "flavor-type"
            applicationIdSuffix ".dev"
        }
        staging {
            dimension "flavor-type"
            applicationIdSuffix ".stg"
        }
        production {
            dimension "flavor-type"
            applicationIdSuffix ".prd"
        }
    }
```
* `productFlavors`内の`develop{}`、`staging{}`、`production{}`は各環境の設定をしています。
    * (名前に決まりはないので、`dev{}`、`stg{}`、`prd{}`とかでもおｋです。)
* `applicationIdSuffix`で指定した""はパッケージ名に紐づきます。
    * 例えば、パッケージ名が"com.example"で、applicationIdSuffix ".dev"と指定すると、dev環境でbuiildするとパッケージ名は"com.exapmle.dev"となります。

その他の書き方や意味については、この記事の一番下にある参考文献を見て頂ければ理解できると思います。

### 3. 各環境のmain.dartを作成
* 環境ごとのmainファイルを3つ作成していきます。
    * main.dartは今回使わないので、消しておｋです。

```main_dev.dart
import 'package:flutter/material.dart';
import 'appEntry.dart';
import 'configs/config.dart';

void main() {
  Config.environment = Flavor.DEVELOP;
  runApp(MyApp());
}
```

```main_stg.dart
import 'package:flutter/material.dart';
import 'appEntry.dart';
import 'configs/config.dart';

void main() {
  Config.environment = Flavor.STAGING;
  runApp(MyApp());
}
```

```main_prd.dart
import 'package:flutter/material.dart';
import 'appEntry.dart';
import 'configs/config.dart';

void main() {
  Config.environment = Flavor.RELEASE;
  runApp(MyApp());
}
```

* `void main(){}`内の`Config.environment = Flavor.[環境];`は、各環境のmainファイルが読み込まれたときに、`Config`の`environment`にEnum型Flavorクラスで定義されている定数を代入しています。(→「4. configs/config.dartを作成」で出てきます。)
* 上記のファイルでimportしている、`appEntry.dart`、`configs/config.dart`に関しては下記で追記していきます。


### 4. configs/config.dartを作成
* `config.dart`では、Enumで環境を宣言したり、環境によって値を変えたりする関数を定義しています。

(configsファイルを作成し、その中に`config.dart`を入れているのですが、今回は特に意味ないので`lib/config.dart`でもおｋですね。)

```configs/config.dart
import 'package:flutter/material.dart';

enum Flavor {
  DEVELOP,
  STAGING,
  RELEASE,
}

class Config {
  static Flavor environment;

  static String getString() {
    switch (environment) {
      case Flavor.DEVELOP:
        return "DEVELOP";
      case Flavor.STAGING:
        return "STAGING";
      case Flavor.RELEASE:
        return "RELEASE";
      default:
        return "環境エラー";
    }
  }
}
```
今回は、buildしたアプリが何の環境なのかを分かりやすくするため、`getString()`を定義してみました。


### 5. appEntry.dartの作成
* `appEntry.dart`は各環境のmainファイルから呼ばれるファイルです。

```appEntry.dart
import 'package:flutter/material.dart';
import 'configs/config.dart';

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'flutterApp',
      initialRoute: "top",
      routes: {
        "top": (context) => HomePage(),
      },
    );
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Center(
          child: Text(
            Config.getString(),
          ),
        ),
      ),
    );
  }
}
```
`configs/config.dart`で定義した`Config.getString()`をTextウィジェットで表示させるようにしました。
これで準備おｋです。

### 6. 環境ごとにbuildする方法
#### Android studioでbuild
1. Android studioの上部にある`main.dart`(下記画像参照)を押して「Edit Configurations...」を押します。(既にmain.dartを消した人は少し違うかもしれないです。)
![スクリーンショット 2020-05-04 16.32.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185888/1d81f7ef-b92a-dc39-2238-27d7cd228898.png)
2. このような画面が出るので、左上の+ボタンを押し、項目からFlutterを選択してください。
![スクリーンショット 2020-05-04 16.35.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185888/e740d471-8c17-d23d-480d-e196b6d155b7.png)



3. 新規作成できたら、項目を設定していきます。(下記画像はdevelop環境の様子)

* `Name`は、mainファイルの名前と同様の名前が無難で良いと思います。
* `Dart entrypoint`は、mainファイルのPATHなので、指定しましょう。
* `Additional arguments`は、オプション指定するところで、今回Flavorを使っているので、`--flavor [環境]`を指定しましょう。

![スクリーンショット 2020-05-04 16.47.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/185888/838b9a8e-f417-cf30-81e3-789f140aa1a5.png)
4. 2~3を繰り返して残りの環境を作りましょう。
5. 設定が終わったら、1の画像のところに各環境のmainファイルが出てくると思うので、各環境でbuildを試してみましょう。

#### コマンド上でbuild
* コマンド上では、以下の指定方法でbuild出来ます。

```
$ flutter run --flavor develop -t lib/main_dev.dart    //開発環境
$ flutter run --flavor staging -t lib/main_stg.dart    //ステージング環境
$ flutter run --flavor production -t lib/main_prd.dart //商用環境
```
エミュレータや実機など、複数の端末を起動・接続している場合は、`-d [端末名]`を付けることでアプリを起動する端末を指定できます。


以上です！参考になれば幸いです。

## 参考にさせて頂いた文献
* Flavor iOS
    * https://medium.com/flutter-jp/flavor-b952f2d05b5d
* Flavor iOS/Android
    * https://medium.com/@salvatoregiordanoo/flavoring-flutter-392aaa875f36
* Flavor Android
    * https://qiita.com/rottonton/items/579ad9273c5d01cf73f9 
* 参考にしたコード
    * https://github.com/iakta/flutter_flavors