You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在AppDelegate.swift中访问Flutter的dart-define定义变量

解决iOS端通过--dart-define传递Google Maps API密钥无法读取的问题

问题根源

Flutter 传递的--dart-define参数不会直接作为独立环境变量暴露给iOS原生层,而是会将所有键值对编码为Base64字符串,用逗号拼接后存入DART_DEFINES环境变量中。直接用ProcessInfo.processInfo.environment读取GOOGLE_MAPS_API_KEY自然会返回空值。


解决方法1:解析DART_DEFINES提取密钥

在AppDelegate.swift中添加解码逻辑,从DART_DEFINES中提取目标API密钥:

import UIKit
import Flutter
import GoogleMaps

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    // 解析DART_DEFINES环境变量
    if let dartDefines = ProcessInfo.processInfo.environment["DART_DEFINES"] {
      let decodedPairs = dartDefines.components(separatedBy: ",").compactMap { encodedItem in
        Data(base64Encoded: encodedItem)?.toString()
      }
      
      // 遍历提取GOOGLE_MAPS_API_KEY
      for pair in decodedPairs {
        if pair.starts(with: "GOOGLE_MAPS_API_KEY=") {
          let apiKey = pair.components(separatedBy: "=")[1]
          GMSServices.provideAPIKey(apiKey)
          break
        }
      }
    }
    
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

// 扩展Data类型,方便转换为字符串
extension Data {
    func toString() -> String? {
        return String(data: self, encoding: .utf8)
    }
}

解决方法2:通过MethodChannel传递密钥(更简洁)

跳过原生层解析,由Dart端读取--dart-define后直接传递给iOS原生:

  1. Dart端代码
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';

class MapApiKeyHandler {
  static const _channel = MethodChannel('com.yourapp.map_api_key');

  static Future<void> passApiKeyToNative() async {
    // 从dart-define中读取密钥
    const apiKey = String.fromEnvironment('GOOGLE_MAPS_API_KEY');
    await _channel.invokeMethod('setGoogleMapsApiKey', {'key': apiKey});
  }
}

// 在应用启动时调用
void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await MapApiKeyHandler.passApiKeyToNative();
  runApp(const YourApp());
}
  1. iOS原生端代码
import UIKit
import Flutter
import GoogleMaps

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  private let channel = FlutterMethodChannel(name: "com.yourapp.map_api_key", binaryMessenger: UIApplication.shared.delegate as! FlutterBinaryMessenger)
  
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    // 监听MethodChannel调用
    channel.setMethodCallHandler { call, result in
      if call.method == "setGoogleMapsApiKey" {
        guard let args = call.arguments as? [String: String],
              let apiKey = args["key"] else {
          result(FlutterError(code: "INVALID_ARGS", message: "API key missing", details: nil))
          return
        }
        GMSServices.provideAPIKey(apiKey)
        result(nil)
      } else {
        result(FlutterMethodNotImplemented)
      }
    }
    
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

辅助排查步骤

  • 执行flutter clean后重新构建项目,清除缓存导致的配置异常
  • 检查Xcode Scheme配置:打开Runner项目 → Edit Scheme → Run → Arguments → Environment Variables,确保没有手动添加GOOGLE_MAPS_API_KEY或DART_DEFINES,避免覆盖Flutter传递的值
  • 确保使用的Flutter版本为1.17+,早期版本对--dart-define的支持存在局限

内容的提问来源于stack exchange,提问作者coolerneo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 12:10:02