likes
comments
collection
share

Flutter配置多环境,并根据环境区分APP名称

作者站长头像
站长
· 阅读数 1

开发过程中,我们通常需要对接后端不同的环境,比如:开发环境,测试环境,生产环境。测试也需要区分当前包是测试还是生产环境。

  • flutter中为我们提供了--dart-define,我们可以通过flutter运行的命令获取自定义的变量,我们可以用此来区分当前是什么环境

例如:

  • 我们定义一个变量叫APP_ENV,用来区分环境,运行命令如下:
  • dev就是APP_ENV变量的值
flutter run --dart-define=APP_ENV=dev 

一、根据运行命令,区分环境api

1. 新增文件,配置对应的环境api

这里可以自己定义,不一定非按照我这个来

lib/env/env_config.dart

class EnvConfig {
  final String envName;
  final String envHttpUrl;
  final String envTcpIp;
  final int envTcpPort;

  EnvConfig(
      {required this.envName,
      required this.envHttpUrl,
      required this.envTcpIp,
      required this.envTcpPort});
}

2. 通过String.fromEnvironment获取变量的值

lib/env/env.dart

import 'package:planx_app/env/env_config.dart';

class Env {
  // 当前环境
  // 运行: flutter run --dart-define=APP_ENV=dev
  static const _appEnv = String.fromEnvironment("APP_ENV", defaultValue: 'dev');

  // 当前环境配置
  static EnvConfig get envConfig => _getEnvConfig();
  static EnvConfig _getEnvConfig() {
    switch (_appEnv) {
      case "pro":
        return _proConfig;
      case "test":
        return _testConfig;
      default:
        return _devConfig;
    }
  }

  // 开发环境
  static final EnvConfig _devConfig = EnvConfig(
      envName: "development",
      envHttpUrl: "https://testxxxx:/api/v1",
      envTcpIp: "192.168.1.68",
      envTcpPort: 28799);

  // 测试环境
  static final EnvConfig _testConfig = EnvConfig(
      envName: "test",
      envHttpUrl: "http:testxxxx:3000",
      envTcpIp: "192.168.1.75",
      envTcpPort: 1573);

  // 生产环境
  static final EnvConfig _proConfig = EnvConfig(
      envName: "production",
      envHttpUrl: "http:proxxxx:3000",
      envTcpIp: "192.168.1.75",
      envTcpPort: 1573);
}

在其他地方,获取当前运行环境的api地址:

Env.envConfig.envHttpUrl

二、配置VScode调试文件

主要为了在调试模式下也能区分环境

项目根目录下:

Flutter配置多环境,并根据环境区分APP名称

.vscode/launch.json

{
  "configurations": [
    {
      "name": "Flutter (dev)",
      "request": "launch",
      "type": "dart",
      "args": [
        "--dart-define",
        "APP_ENV=dev"
      ]
    },
    {
      "name": "Flutter (pro)",
      "request": "launch",
      "type": "dart",
      "args": [
        "--dart-define",
        "APP_ENV=pro"
      ]
    },
    {
      "name": "Flutter (test)",
      "request": "launch",
      "type": "dart",
      "args": [
        "--dart-define",
        "APP_ENV=test"
      ]
    }
  ]
}

选择调试即可看到,可以选择不同环境运行了

Flutter配置多环境,并根据环境区分APP名称

三、根据不同的环境配置app name

我们也可以通过以下的方式自定义包名和BUNDLE_ID,可以在同一台设备下载两个不同环境的app。但由于我们项目的包名与某些第三方功能绑定较深,单独设置太麻烦,就不做这样的设置了。

iOS

1. 在Flutter下新建文件:

  • 文件名可自定义 ios/Flutter/DartEnv.xcconfig

设置默认值:

APP_ENV=dev

2. 在分别在debug和release中引入配置

ios/Flutter/Debug.xcconfig

ios/Flutter/Release.xcconfig

#include "Generated.xcconfig"
#include "DartEnv.xcconfig"

3. 修改app name

ios/Runner/Info.plist

	<key>CFBundleDisplayName</key>
	<string>${APP_ENV}</string>

4. 此时我们运行app,会发现app名称已经更改为dev

  • 这个是默认值,接下来我们需要将flutter运行时的--dart-define替换这个默认值

5. 编辑schema,替换默认值

Flutter配置多环境,并根据环境区分APP名称

a. 选择pre-action,添加script脚本。

Flutter配置多环境,并根据环境区分APP名称

b. 添加脚本,并且将结果放到:Flutter/DartEnvConfig.xcconfig文件中,这个文件会自动生成

# Type a script or drag a script file from your workspace to insert its path.
function entry_decode() { echo "${*}" | base64 --decode; }

IFS=',' read -r -a define_items <<< "$DART_DEFINES"

result=[]
resultIndex=0

for index in "${!define_items[@]}"
do
    if [ $(entry_decode "${define_items[$index]}") == "APP_ENV=dev" ]; then
        result[$resultIndex]="APP_NAME=PlanX_Test";
        resultIndex=$((resultIndex+1))
    fi
    
    if [ $(entry_decode "${define_items[$index]}") == "APP_ENV=test" ]; then
        result[$resultIndex]="APP_NAME=PlanX_Test";
        resultIndex=$((resultIndex+1))
    fi

    if [ $(entry_decode "${define_items[$index]}") == "APP_ENV=pro" ]; then
        result[$resultIndex]="APP_NAME=PlanX";
        resultIndex=$((resultIndex+1))
    fi
done

printf "%s\n" "${result[@]}"|grep '^APP_' > ${SRCROOT}/Flutter/DartEnvConfig.xcconfig

6. 在分别在debug和release中引入配置DartEnvConfig.xcconfig

  • ios/Flutter/Debug.xcconfig
  • ios/Flutter/Release.xcconfig
#include "Generated.xcconfig"
#include "DartEnv.xcconfig"
#include "DartEnvConfig.xcconfig"

7. 动态配置值

ios/Runner/Info.plist

<key>CFBundleDisplayName</key>
<string>${APP_NAME}</string>

8. 重新运行,我们会发现文件自动生成了,内容是:

Flutter配置多环境,并根据环境区分APP名称

并且app名称也更改了

Flutter配置多环境,并根据环境区分APP名称Flutter配置多环境,并根据环境区分APP名称

Android

1. 新增变量接收--dart-define的值

android/app/build.gradle

def dartEnv = [
    APP_ENV: 'dev',
]

if (project.hasProperty('dart-defines')) {
    dartEnv = dartEnv + project.property('dart-defines')
        .split(',')
        .collectEntries { entry ->
            def pair = new String(entry.decodeBase64(), 'UTF-8').split('=')
            [(pair.first()): pair.last()]
        }
}

2. 添加变量值到defaultConfig中

android/app/build.gradle

定义resValue,用于新增变量 (PlanX是我app的名称)

android {
    defaultConfig {
        resValue "string","app_name","PlanX${dartEnv.APP_ENV=='pro'?'':'_Test'}"
    }
}

3. 动态更改app name

android/app/src/main/AndroidManifest.xml

 <application
        android:label="@string/app_name">

运行测试:

Flutter配置多环境,并根据环境区分APP名称Flutter配置多环境,并根据环境区分APP名称