Flutter中安全注入Google Maps API密钥(iOS端配置遇阻)
iOS Flutter Google Maps API密钥配置失败的调试与修复
一、先验证脚本是否能正常工作
手动测试脚本逻辑
给脚本添加执行权限:chmod +x ios/extract-defines.sh手动模拟DART_DEFINES环境变量并运行脚本:
cd ios DART_DEFINES="$(echo "GOOGLE_MAPS_API=your_actual_ios_key" | base64)" ./extract-defines.sh打开
Flutter/Dart-Defines.xcconfig,检查是否包含GOOGLE_MAPS_API=your_actual_ios_key。如果没有,排查脚本问题:- 适配base64命令:把脚本里的
base64 --decode改成base64 --decode 2>/dev/null || base64 -D(兼容不同macOS版本) - 检查过滤规则:确认你的密钥变量名不以
flutter开头(脚本会过滤这类变量)
- 适配base64命令:把脚本里的
查看Xcode构建时的脚本输出
在Xcode的Build Phases->Run Script中,给脚本开头添加日志打印:echo "=== Extracting Dart Defines ===" echo "DART_DEFINES: $DART_DEFINES" echo "Output file path: $OUTPUT_FILE"构建项目后,查看Xcode的
Report Navigator对应构建记录的Build日志,搜索这些打印内容,确认:- DART_DEFINES是否有有效值(应为逗号分隔的base64字符串)
- 脚本是否执行到写入文件的步骤
二、检查Xcode配置是否正确
确认脚本位置与执行顺序
- 脚本需放在
ios目录下,Run Script中的路径应为${SRCROOT}/extract-defines.sh - 确保Run Script阶段排在
[CP] Generate Pods Project之后、[CP] Embed Pods Frameworks之前
- 脚本需放在
确保Xcode加载生成的xcconfig
Flutter默认使用Flutter/Generated.xcconfig,需让它包含脚本生成的文件:
打开ios/Flutter/Generated.xcconfig,添加一行:# include "Dart-Defines.xcconfig"这样Xcode才能读取到脚本生成的环境变量
三、验证环境变量是否正确传递
Flutter运行时传递参数
运行项目时必须通过--dart-define传递密钥:flutter run --dart-define=GOOGLE_MAPS_API=your_actual_ios_keyIDE运行配置需添加对应参数:
- VSCode:在
.vscode/launch.json的args数组中加入"--dart-define=GOOGLE_MAPS_API=your_actual_ios_key" - Android Studio:在Run/Debug Configurations的
Additional run args中添加该参数
- VSCode:在
Xcode Scheme手动配置(直接用Xcode运行时)
- 打开Xcode ->
Product->Scheme->Edit Scheme - 选择
Run->Arguments->Environment Variables,添加DART_DEFINES,值为$(echo "GOOGLE_MAPS_API=your_actual_ios_key" | base64)
- 打开Xcode ->
四、验证Info.plist与AppDelegate
检查Info.plist变量替换结果
构建完成后验证变量是否替换成功:- Xcode ->
Product->Show Build Folder in Finder - 进入
Build/Products/Debug-iphonesimulator,右键.app文件 ->Show Package Contents - 打开
Info.plist,查看GOOGLE_MAPS_API的值是否为实际密钥,而非$(GOOGLE_MAPS_API)
- Xcode ->
添加日志验证AppDelegate读取逻辑
修改AppDelegate.swift,添加日志打印:override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { if let googleMapsApiKey = Bundle.main.object(forInfoDictionaryKey: "GOOGLE_MAPS_API") as? String { print("Loaded Google Maps API Key: \(googleMapsApiKey)") GMSServices.provideAPIKey(googleMapsApiKey) } else { print("Google Maps API Key NOT found!") } return super.application(application, didFinishLaunchingWithOptions: launchOptions) }运行项目后查看Xcode控制台输出,确认密钥是否被正确读取
五、后续Android端配置提示
Android端可通过build.gradle读取DART_DEFINES:
- 在
android/app/build.gradle中添加:def dartDefines = [] if (project.hasProperty('dart.defines')) { dartDefines = project.property('dart.defines').split(',') } def googleMapsApiKey = "" dartDefines.each { define -> def decoded = new String(define.decodeBase64()) if (decoded.startsWith("GOOGLE_MAPS_API=")) { googleMapsApiKey = decoded.split('=')[1] } } android { defaultConfig { manifestPlaceholders = [GOOGLE_MAPS_API_KEY: googleMapsApiKey] } } - 在
AndroidManifest.xml中引用:<meta-data android:name="com.google.android.geo.API_KEY" android:value="${GOOGLE_MAPS_API_KEY}" />
内容的提问来源于stack exchange,提问作者Abdulrahmna Magdy
相关产品推荐
相关产品推荐

