【问题标题】:Setting environment variables in Flutter在 Flutter 中设置环境变量
【发布时间】:2017-10-30 05:12:26
【问题描述】:

例如,为 API 构建客户端,例如 Twitch。

在 Dart CLI 二进制文件中,我可以使用通用环境变量或 Dart 定义变量。例如,将两者都用作后备:

main() {
  String clientId = 
      // dart -dCLIENT_ID='abc bin/example.dart
      // This is considered "compiled-into" the application.
      const String.fromEnvironment('CLIENT_ID') ??

      // CLIENT_ID='abc' dart bin/example.dart
      // This is considered a runtime flag.
      Platform.environment['CLIENT_ID'];

  // Use clientId.
}

Flutter 是否有办法设置其中一个/两个,特别是...

  • 在开发期间
  • 运送到产品时

一旦我弄清楚如何帮助一些文档,我很高兴:)

【问题讨论】:

标签: dart flutter


【解决方案1】:

从 Flutter 1.17 开始,您可以根据需要定义编译时变量。

为此,只需在flutter runflutter build 期间使用--dart-define 参数

如果需要传递多个键值对,只需定义--dart-define多次即可:

flutter run --dart-define=SOME_VAR=SOME_VALUE --dart-define=OTHER_VAR=OTHER_VALUE

然后,您可以在代码中的任何位置使用它们,例如:

const SOME_VAR = String.fromEnvironment('SOME_VAR', defaultValue: 'SOME_DEFAULT_VALUE');
const OTHER_VAR = String.fromEnvironment('OTHER_VAR', defaultValue: 'OTHER_DEFAULT_VALUE');

此外,它们也可以在原生层中使用。

Here is an article that explains more.

【讨论】:

  • 要传递多个键值对,也可以使用以下语法:--dart-define=FIRST_VAR=first_value,SECOND_VAR=second_value(使用逗号,不重复--dart-define=
  • 是否可以在 AppDelegate.swift 中访问这个环境变量?
  • @JoseTapizquent 我没试过,但我可以假设你总是可以将你的 dart 定义值添加到 plist 文件中并从那里读取
  • @JoseTapizquent 是的,你可以。检查这个答案stackoverflow.com/a/59590990/1843853
  • 请注意const 是必需的!请参阅答案中的文章和github.com/flutter/flutter/issues/55870 我无法使其正常工作,因为我没有意识到
【解决方案2】:

对于配置,我见过的一种常见模式是使用单独的主文件。即

flutter run -t lib/production_main.dart

flutter build apk -t lib/debug_main.dart

然后在这些不同的主文件中设置所需的配置。

在读取 id 方面,您可以从任意资产 https://flutter.io/assets-and-images/ 中做到这一点。

我相信在 Flutter 中可以按照您的建议从环境中读取数据,但是我不知道如何在 iOS 或 Android 上设置这些环境变量。

【讨论】:

【解决方案3】:

由于我也试图解决这个问题并且遇到了这个线程,所以我只是想为将来寻找解决方案的人们添加这个......如果您正在寻找的只是 PROD/DEV 环境,那么现在有一个支持获取应用程序是否处于生产状态的方式:

const bool isProduction = bool.fromEnvironment('dart.vm.product');

根据以下建议:

https://twitter.com/FlutterDev/status/1048278525432791041

https://github.com/flutter/flutter/issues/4014

【讨论】:

    【解决方案4】:

    我使用简单的 shell 脚本来生成 dart 定义。在我的应用中有 3 种构建风格:devstagingprod。环境变量在常规 .env 文件中定义。

    env/
    ├── dev.env
    ├── prod.env
    └── staging.env
    

    这是从.env 文件生成dart-defines 的脚本。

    #!/bin/bash
    
    # scripts/generate_dart_defines.sh
    
    case "$1" in
    "dev") INPUT="env/dev.env"
    ;;
    "staging") INPUT="env/staging.env"
    ;;
    "prod") INPUT="env/prod.env"
    ;;
    *)
      echo "Missing arguments [dev|staging|prod]"
      exit 1
    ;;
    esac
    
    while IFS= read -r line
    do
      DART_DEFINES="$DART_DEFINES--dart-define=$line "
    done < "$INPUT"
    echo "$DART_DEFINES"
    

    这是触发构建的脚本。

    #!/bin/bash
    
    # build.sh
    
    if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then
      echo -e "Missing arguments: [apk|appbundle|ios] [release|debug|profile] [dev|staging|prod]"
      # invalid arguments
      exit 128
    fi
    
    DART_DEFINES=$(scripts/generate_dart_defines.sh $3)
    
    if [ $? -ne 0 ]; then
      echo -e "Failed to generate dart defines"
      exit 1
    fi
    
    echo -e "artifact: $1, type: $2, flavor: $3\n"
    echo -e "DART_DEFINES: $DART_DEFINES\n"
    
    eval "flutter build $1 --$2 --flavor $3 $DART_DEFINES"
    

    脚本接受 3 个参数。第一个是工件apkappbundleios。第二个是构建类型releasedebugprofile。第三个是构建风格,devstagingprod

    ./build.sh apk release prod
    

    请注意,您还需要为不同的构建风格分别配置 android 和 ios。 https://developer.android.com/studio/build/build-variants

    https://shockoe.com/ideas/development/how-to-setup-configurations-and-schemes-in-xcode/

    https://developer.apple.com/library/archive/documentation/ToolsLanguages/Conceptual/Xcode_Overview/ManagingSchemes.html

    【讨论】:

      【解决方案5】:

      运行您的应用程序(flutter run

      • flutter run --dart-define=EXAMPLE_API_ENDPOINT=https://api.example.com/

      发布你的应用(flutter build

      我的应用程序不允许用户登录我意识到环境变量在应用程序中是空字符串,而不是它们的实际值?。

      • iOS: flutter build ipa --dart-define=EXAMPLE_API_ENDPOINT=https://api.example.com/
      • 安卓: flutter build apk --dart-define=EXAMPLE_API_ENDPOINT=https://api.example.com/

      --dart-define 文档

      flutter run --helpflutter build ipa --help--dart-define 显示:

      Additional key-value pairs that will be available as 
      constants from the String.fromEnvironment, bool.fromEnvironment, 
      int.fromEnvironment, and double.fromEnvironment constructors. 
      Multiple defines can be passed by repeating "--dart-define" 
      multiple times.
      

      【讨论】:

        【解决方案6】:

        创建一个类:

        import 'package:flutter/foundation.dart';
        
        class AppUtils {
          static String get clientId {
            if (kDebugMode) return 'debug_id';
            else if (kProfileMode) return 'profile_id';
            else if (kReleaseMode) return 'production_id';
            else if (kIsWeb) return 'web_mode_id';
            
            throw ArgumentError('No mode detected');
          }
        }
        

        用法:

        var id = AppUtils.clientId;
        

        【讨论】:

        • 我认为这通常是一个干净的答案,但至少对我来说它不适合我的用例。就我而言,我想在自动化测试期间显示和检测 Crashlytics 错误。因此,我想使用一个标志来显示异常,这些异常将在 CI/CD 自动化测试管道中以调试模式可视化记录,以便在测试期间可以轻松检测到错误(无法通过 Appium 轻松读取日志)。所以我有多个运行环境,比如调试模式。
        • @RoboBear 我绝对同意你的观点,它不适合这种情况。
        猜你喜欢
        • 2018-07-13
        • 2011-03-25
        • 2015-02-01
        • 2017-01-01
        • 2012-03-22
        • 2012-06-30
        • 2015-04-06
        • 2019-11-22
        • 2019-11-15
        相关资源
        最近更新 更多