如何在 Flutter 上获取风味名称?

Blo*_*oss 6 dart flutter

是否有可能获得 Flutter 方面的风味名称?适用于 android 和 ios

构建.gradle

flavorDimensions "app"

productFlavors {
    dev {
        dimension "app"
        versionCode 2
        versionName "1.0.0"
    }
    qa {
        dimension "app"
        applicationId "com.demo.qa"
        versionCode 3
        versionName "1.0.2"
    }
}
Run Code Online (Sandbox Code Playgroud)

Til*_*ebe 31

您可以使用jonahwilliams的解决方案。

  1. 创建应用时设置键值对:
flutter build apk --flavor=paid --dart-define=app.flavor=paid
Run Code Online (Sandbox Code Playgroud)
  1. 访问 Dart 中的值:
const String flavor = String.fromEnvironment('app.flavor');

void main() {
  print(flavor);
}
Run Code Online (Sandbox Code Playgroud)

运行时会打印“paid”。

优点是您可以在尚不支持风味且变量为 的平台上使用它const。缺点是您必须为构建设置键值对。

  • 我想,我们可以将风味类型处理为“const”有很多好处,例如设置冻结字段的默认值或函数默认参数。 (2认同)

小智 10

只要每种口味都有不同的 packageName,您就可以这样做:

enum EnvironmentType { dev, qa }

class Environment {
  EnvironmentType current;

  Environment() {
    PackageInfo.fromPlatform().then((PackageInfo packageInfo) {
      switch (packageInfo.packageName) {
        case "com.demo.qa":
          current = EnvironmentType.qa;
          break;
        default:
          current = EnvironmentType.dev;
      }
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,这在网络上不起作用。请改用蒂尔·弗里贝的解决方案。 (2认同)

kfo*_*jan 10

如果您已经按照官方 Flutter 文档中所示设置了风味,则可以使用全局可用变量来访问您在运行应用程序时appFlavor定义的风味名称。变量是services.dart库的一部分。您可以通过导入库来访问它:--flavorappFlavor

import 'package:flutter/services.dart';
Run Code Online (Sandbox Code Playgroud)

现在您可以在代码中使用它,如下所示:

if (appFlavor == 'prod') {
    // do something
  }
Run Code Online (Sandbox Code Playgroud)

解释:

services.dart 中的flavor.dart包含以下代码:

const String? appFlavor = String.fromEnvironment('FLUTTER_APP_FLAVOR') != '' ?
  String.fromEnvironment('FLUTTER_APP_FLAVOR') : null;
Run Code Online (Sandbox Code Playgroud)

这意味着无需在其他任何地方再次定义风味或使用--dart-define来定义风味。您提供的参数--flavor会自动在 FLUTTER_APP_FLAVOR 键下进行 dart 定义,并且可以按照风味.dart中所示的相同方式进行访问。


小智 6

我还没有看到任何描述如何直接从运行时配置获取当前风味的答案,经过大量搜索后我发现这样:对于 Android 来说非常简单,将此代码放入您的 MainActivity.kt 中:


    private val CHANNEL = "flavor_channel"

  override fun configureFlutterEngine(@NonNull flutterEngine: FlutterEngine) {
    super.configureFlutterEngine(flutterEngine)
    MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler {
      call, result ->
            when (call.method) {
                "getFlavor" -> {
                    result.success(BuildConfig.FLAVOR)
                }
            }
    }
  }
Run Code Online (Sandbox Code Playgroud)

对于 iOS,将其放入 AppDelegate.swift 中:

let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let flavorChannel = FlutterMethodChannel(name: "flavor_channel",
                                          binaryMessenger: controller.binaryMessenger)
flavorChannel.setMethodCallHandler({
  (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
  // This method is invoked on the UI thread.
  guard call.method == "getFlavor" else {
    result(FlutterMethodNotImplemented)
    return
  }
  self.receiveCurrentFlavor(result: result)
})
Run Code Online (Sandbox Code Playgroud)

然后在AppDelegate类的底部创建这个方法:

let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let flavorChannel = FlutterMethodChannel(name: "flavor_channel",
                                          binaryMessenger: controller.binaryMessenger)
flavorChannel.setMethodCallHandler({
  (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
  // This method is invoked on the UI thread.
  guard call.method == "getFlavor" else {
    result(FlutterMethodNotImplemented)
    return
  }
  self.receiveCurrentFlavor(result: result)
})
Run Code Online (Sandbox Code Playgroud)

我们现在需要在 infoDictionary 中提供 Flavor。在 Xcode 中,打开 Runner/Info.plist 并添加映射到 ${PRODUCT_FLAVOR} 的键 Flavor: 信息列表

现在,在 Targets/Runner/Build Settings/User-Defined 下添加一个设置 PRODUCT_FLAVOR。为每个配置添加风味名称: 用户定义的设置

然后在达特中:

    private func receiveCurrentFlavor(result: FlutterResult) {
    var config: [String: Any]?
        
    if let infoPlistPath = Bundle.main.url(forResource: "Info", withExtension: "plist") {
        do {
            let infoPlistData = try Data(contentsOf: infoPlistPath)
            
            if let dict = try PropertyListSerialization.propertyList(from: infoPlistData, options: [], format: nil) as? [String: Any] {
                config = dict
            }
        } catch {
            print(error)
        }
    }

    result(config?["Flavor"])
  }
Run Code Online (Sandbox Code Playgroud)

然后你就完成了!