如何在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原生:
- 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()); }
- 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
相关产品推荐
相关产品推荐

