LoginSignup
3
3

More than 3 years have passed since last update.

Flutterで本番/開発 別に切り分けてアプリを入れる

Posted at

概要

Flutterでアプリ開発をしていると、本番アプリ、開発アプリの名前を分けて確認したいことありますよね。
この切替には複数のSchemeを用意する方法、Flavorを使う方法、ビルド時の--releaseと--debugを使って切り分ける方法がありますが、Flutter 1.17からビルド引数の--dart-defineで定数を渡せるようになりました。今回はこの--dart-defineの方法で本番、開発それぞれのアプリをスマホ内に入れる方法を説明します。
Qiita.png

前提

  • Flutterのサンプルプロジェクトを作成しシミュレーターで実行できる
  • Flutter 1.20以降
  • --dart-define の設定ができる(こちらの記事を参照)

環境

$ flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[+ ] Flutter (Channel stable, 1.22.4, on Mac OS X 10.15.7 19H2 darwin-x64, locale en-JP)
[+ ] Android toolchain - develop for Android devices (Android SDK version 30.0.0)
[+ ] Xcode - develop for iOS and macOS (Xcode 12.1)
[+ ] Android Studio (version 4.1)
[+ ] Connected device (1 available)

iOS用の設定

iOSの場合Bundle identiferでアプリを識別しています。この値が同じものだと上書きインストールされてしますので、この値を本番と開発で変える必要があります。

Flutterの設定

以下のように、コンパイル引数で渡します。
開発用
flutter build ios --dart-define=DEFINE_IOS_SUFFIX=.dev
本番用
flutter build ios --dart-define=DEFINE_IOS_SUFFIX=
※ --dart-define の基本的な設定についてはこちらの記事を見てください。(記事中のInfo>Custom iOS Target Propertiesは設定せず、下記'Xcodeの設定'を参考に設定してください)

Xcodeの設定

Build SettingsPackagingにあるProduct Bundle Identifier Debugの値をダブルクリックし、もともとの値の後ろに$(DEFINE_IOS_SUFFIX)を追加します。
Runner_xcodeproj.png

Runner/Info.plistInformation Property ListにあるBundle nameにあるもともとの値の後ろに$(DEFINE_IOS_SUFFIX)を追加します。
Info_plist.png

動作確認

開発用、本番用、それぞれ実行してみてください。
どうでしょうか?スクリーンにDEFINE_IOS_SUFFIXのついたBundle Identiferが表示されたでしょうか。また、ホームスクリーンにも2つのアプリが入ったと思います。
iPhone_SE_–_2nd_generation_–_14_3.png
※ 元の名前が長くて「flutter_define...」となってしまいました。
Qiita.png

Android用の設定

Androidの場合はapplicationIdによってアプリが識別されます。この値を本番と開発とで変えていきます。

Flutterの設定

以下のように、コンパイル引数で渡します。
開発用
flutter build apk --dart-define=DEFINE_APP_NAME=flutter_define_dev --dart-define=DEFINE_APP_SUFFIX=dev
本番用
flutter build apk

Gradleの設定

[project]/android/app/src/main/AndroidManifest.xmlにあるandroid:labelを修正します。

<application
    android:name="io.flutter.app.FlutterApplication"
    android:label="@string/app_name"
    android:icon="@mipmap/ic_launcher">

[project]/android/app/build.gradleを以下のように修正します。

// 〜〜 省略 〜〜
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
    flutterVersionName = '1.0'
}

// ここから追記 --
def dartEnvironmentVariables = [
        DEFINE_APP_NAME: 'flutter_define',
        DEFINE_APP_SUFFIX: null,
];
if (project.hasProperty('dart-defines')) {
    dartEnvironmentVariables = dartEnvironmentVariables + project.property('dart-defines')
            .split(',')
            .collectEntries { entry ->
                def pair = URLDecoder.decode(entry).split('=')
                [(pair.first()): pair.last()]
            }
}
// ここまで追記 --

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"

// 〜〜 省略 〜〜

android {

    defaultConfig {
        applicationId "com.yana1316.flutter_define"
        applicationIdSuffix dartEnvironmentVariables.DEFINE_APP_SUFFIX // 追記
        minSdkVersion 16
        targetSdkVersion 29
        versionCode flutterVersionCode.toInteger()
        versionName flutterVersionName
        resValue "string", "app_name", dartEnvironmentVariables.DEFINE_APP_NAME // 追記
    }

動作確認

開発用、本番用、それぞれ実行してみてください。
どうですか?スクリーンにapplicationIdが表示されたかと思います。また、アプリも2つ入りました。
Android_Emulator_-_Nexus_S_v9_0_5554.png

Android_Emulator_-_Nexus_S_v9_0_5554.png

まとめ

以前はFlavorや複数のShceme、--targetオプションや--rerease--debugオプションなどを使って切り替えていました。Flutter1.17から導入された--dart-defineを使うとシンプルに切り分けができたかと思います。
組織で開発をするときはBitriseやfastlaneが既に導入され、自動的に便利に開発できることも多いと思います。一方、個人開発や初めてFlutterを導入する場合にて、この程度の切り分けがちょうどよいケースもありますので、参考になればと思いました。

参考

3
3
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
3
3