google_maps_flutter_ios_sdk9 使用指南:在 Flutter 中显式启用 Google Maps SDK 9.x(iOS 15+)
【免费下载链接】packagesA collection of useful packages maintained by the Flutter team项目地址: https://gitcode.com/GitHub_Trending/pac/packages
google_maps_flutter_ios_sdk9是 Flutter 官方插件 google_maps_flutter 在 iOS 平台上基于Google Maps SDK 9.x的独立实现包。本文围绕该包 README 的核心脉络,讲解它与默认 iOS 实现的区别、如何在应用中显式切换 SDK 版本、API Key 与最低部署版本的配置步骤,并结合仓库源码(Dart 平台层、Swift 原生层、Podspec 与 Package.swift)说明其实现原理,最后给出 SDK 9.x 下热力图(Heatmap)选项的完整支持矩阵,帮助你为不同 iOS 最低版本目标选择正确的实现方案。
一、这个包是什么:SDK 9.x 专用的 iOS 实现
google_maps_flutter_ios_sdk9是google_maps_flutter的一个 iOS 实现,底层直接基于Google Maps SDK for iOS 9.x。它不是一个独立的地图插件,而是 Flutter 官方"联邦式插件"(federated plugin)体系中的一个平台实现包。
从仓库中的 pubspec.yaml 可以看到它的插件声明:
flutter: plugin: implements: google_maps_flutter platforms: ios: pluginClass: GoogleMapsPlugin dartPluginClass: GoogleMapsFlutterIOSimplements: google_maps_flutter:声明自己是google_maps_flutter的一个实现;pluginClass: GoogleMapsPlugin:原生 iOS 侧入口类(Swift);dartPluginClass: GoogleMapsFlutterIOS:Dart 侧平台接口实现类,对应源码 lib/src/google_maps_flutter_ios.dart 中的GoogleMapsFlutterIOS,它实现GoogleMapsFlutterPlatform接口,并在registerWith()中完成平台实例的注册。
这意味着应用代码仍然像往常一样使用google_maps_flutter的GoogleMap组件,具体的原生渲染由本包接管,Dart 侧 API 无需任何改动。
与默认 iOS 实现的差异
Flutter 官方在 google_maps_flutter_ios 中说明了二者的分工:
| 对比项 | google_maps_flutter_ios(默认) | google_maps_flutter_ios_sdk9(本包) |
|---|---|---|
| 是否 endorsed 默认实现 | 是,自动引入 | 否,需显式添加依赖 |
| 底层 SDK | 8.4 / 9.x / 10.x 按最低部署版本自动选择 | 固定 Google Maps SDK 9.x |
| 最低 iOS 版本 | iOS 14 | iOS 15 |
| Swift Package Manager | 不支持(CocoaPods 无法按部署版本自动选 SDK) | 支持,可直接使用 SPM |
| 未来新特性更新 | 不再接收新功能更新 | 持续维护的 SDK 定向实现 |
从源码结构看,官方提供了_ios_sdk9、_ios_sdk10等 SDK 定向实现,让应用可以按自己的最低 iOS 版本目标锁定具体的 Google Maps SDK 大版本,而不是依赖默认包自动选择。
二、使用方式:如何显式切换到 SDK 9.x 实现
本包不是默认的 endorsed 版本,因此想要使用 Google Maps SDK 9.x,必须在应用的pubspec.yaml中显式声明对该包的依赖:
dependencies: google_maps_flutter: ^2.18.0 # 主包,提供 GoogleMap 组件与 Dart API google_maps_flutter_ios_sdk9: ^2.18.0 # 显式选择 SDK 9.x 的 iOS 实现添加依赖后,它会自动替换默认的 iOS 实现,应用代码继续像往常一样使用google_maps_flutter即可,无需修改任何 Dart 代码:
import 'package:google_maps_flutter/google_maps_flutter.dart'; GoogleMap( initialCameraPosition: const CameraPosition( target: LatLng(37.42796133580664, -122.085749655962), zoom: 14.4746, ), )给插件/包作者的注意事项
如果你正在编写一个依赖地图功能的第三方包,请不要直接依赖google_maps_flutter_ios_sdk9这类具体平台实现包,除非有非常明确的原因。正确做法是只依赖google_maps_flutter主包:
dependencies: google_maps_flutter: ^2.18.0这样做的原因是:SDK 版本的选择权应保留给最终应用开发者,由他们根据自己应用的最低 iOS 版本目标来决定使用 SDK 8.4(iOS 14)、SDK 9.x(iOS 15)还是 SDK 10.x(iOS 16+)。如果包作者锁死了具体实现包,会剥夺应用开发者的这一选择权,并可能与其最低 iOS 版本目标冲突。
替换机制的原理
替换之所以"自动"生效,是因为联邦式插件(endorsed federated plugin)机制:google_maps_flutter通过google_maps_flutter_platform_interface定义抽象平台接口,而 Dart 侧实现类GoogleMapsFlutterIOS在注册后会将GoogleMapsFlutterPlatform.instance指向自身(见 google_maps_flutter_ios.dart)。当应用中同时存在默认实现与本包时,显式依赖的包优先,从而完成 SDK 版本的切换。
三、Setup:API Key 与 iOS 15 最低版本要求
1. 在 AppDelegate 中配置 API Key
在ios/Runner/AppDelegate.swift中调用GMSServices.provideAPIKey配置你的 API Key:
import UIKit import Flutter import GoogleMaps @UIApplicationMain @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { GMSServices.provideAPIKey("YOUR KEY HERE") GeneratedPluginRegistrant.register(with: self) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } }仓库自带的 example 应用 AppDelegate.swift 给出了更贴近 CI/多环境的写法——从环境变量MAPS_API_KEY读取 Key,未设置时回退到占位符:
@main @objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate { override func application( _ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? ) -> Bool { var mapsApiKey = ProcessInfo.processInfo.environment["MAPS_API_KEY"] ?? "YOUR KEY HERE" GMSServices.provideAPIKey(mapsApiKey) return super.application(application, didFinishLaunchingWithOptions: launchOptions) } func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) { GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry) } }2. 更新最低 iOS 部署版本到 15.0
Google Maps SDK 9.x 要求 iOS 15,因此如果你的应用还没有将最低 iOS 部署版本提升到 iOS 15,必须同步更新:
- 在 Xcode 中修改 Project → Build Settings →iOS Deployment Target为
15.0; - 或直接编辑
ios/Podfile/ios/Runner.xcodeproj/project.pbxproj中的部署版本字段。
这一点在包的原生声明中有双重印证:
- google_maps_flutter_ios_sdk9.podspec 中声明
s.platform = :ios, '15.0'; - Package.swift 中声明
platforms: [.iOS(.v15)]。
如果你需要继续支持iOS 14,请改用google_maps_flutter_ios(默认实现,支持 iOS 14,底层按需使用 SDK 8.4 / 9.x / 10.x)。
3. 依赖与构建约束
从 pubspec.yaml 可以看到运行环境要求:
- Dart SDK:
^3.10.0; - Flutter:
>=3.38.0; - 依赖
google_maps_flutter_platform_interface、meta、stream_transform。
原生侧依赖(见 podspec 与 Package.swift):
- GoogleMaps SDK:
~> 9.2(SPM 中为"9.2.0"..<"10.0.0",即 9.x 全系列); - Google-Maps-iOS-Utils:
>= 6.0, <= 6.1.0(SPM 中为"6.0.0"..<"6.1.3")——因为 Google-Maps-iOS-Utils 6.1.3 起切换到了 Google Maps SDK 10.x,且未做 major 版本号变更,所以必须锁住这个区间; - Swift 版本:5.9;
- 以静态 framework 方式集成(
s.static_framework = true)。
原生入口 GoogleMapsPlugin.swift 注册了 id 为plugins.flutter.dev/google_maps_ios的 PlatformView 工厂,并调用GMSServices.addInternalUsageAttributionID完成使用归因标记;Dart 侧 _buildView 通过UiKitView以该 viewType 创建原生视图。
四、SDK 9.x 下支持的热力图选项
本包 README 以表格形式明确了 Heatmap 相关选项在 iOS SDK 9.x 实现中的支持情况,这里逐项说明:
| 字段 | 是否支持 |
|---|---|
| Heatmap.dissipating | ✗ |
| Heatmap.maxIntensity | ✗ |
| Heatmap.minimumZoomIntensity | ✓ |
| Heatmap.maximumZoomIntensity | ✓ |
| HeatmapGradient.colorMapSize | ✓ |
为什么会存在不支持的字段
从原生实现 HeatmapController.swift 可以看出,iOS 侧热力图是基于 Google-Maps-iOS-Utils 的GMUHeatmapTileLayer(瓦片图层)实现的:
heatmapTileLayer.weightedData = platformHeatmap.data.map { $0.toGMUWeightedLatLng() } if let gradient = platformHeatmap.gradient { heatmapTileLayer.gradient = gradient.toGMUGradient() } heatmapTileLayer.opacity = Float(platformHeatmap.opacity) heatmapTileLayer.radius = UInt(platformHeatmap.radius) heatmapTileLayer.minimumZoomIntensity = UInt(platformHeatmap.minimumZoomIntensity) heatmapTileLayer.maximumZoomIntensity = UInt(platformHeatmap.maximumZoomIntensity) // 每次更新必须重新设置 map,且放在最后,避免默认值造成视觉闪烁。 heatmapTileLayer.map = mapView由于GMUHeatmapTileLayer以固定瓦片方式渲染,dissipating(热度随缩放消散)与maxIntensity(最大强度截断)这两个 Android 端支持、依赖逐点渲染能力的选项在 iOS 端不被支持;而缩放强度上下限minimumZoomIntensity/maximumZoomIntensity以及渐变colorMapSize则由GMUHeatmapTileLayer原生支持,因此标记为 ✓。Dart 侧 _platformHeatmapFromHeatmap 将minimumZoomIntensity、maximumZoomIntensity、gradient.colorMapSize等字段逐一映射到 Pigeon 生成的PlatformHeatmap,再经 method channel 传给原生层。
提示:如果你的应用依赖
dissipating或maxIntensity行为,需要在 iOS 上做降级处理(例如通过自定义渐变与透明度模拟视觉效果),并在 Android 与 iOS 之间做平台差异化实现。
五、选型建议:什么时候用 SDK 9.x 实现
结合官方 google_maps_flutter_ios 与 google_maps_flutter 的说明,可以按以下规则选择 iOS 实现:
- 最低 iOS 15+,且希望锁定 Google Maps SDK 9.x:使用本包
google_maps_flutter_ios_sdk9; - 最低 iOS 16+:可升级到
google_maps_flutter_ios_sdk10,使用 Google Maps SDK 10.x; - 需要支持 iOS 14:使用默认的
google_maps_flutter_ios(SDK 8.4 起,按部署版本自动选择 SDK 大版本),但需要注意该包不再接收新功能更新,官方建议所有客户端迁移到 SDK 定向实现; - 希望用 Swift Package Manager 而非 CocoaPods 集成:必须使用 SDK 定向实现(本包支持 SPM,默认实现不支持)。
具体到本包:在 example 中,官方提供了完整的可运行示例,覆盖 marker、polyline、polygon、circle、ground overlay、tile overlay、聚类(clustering)、高级 marker(advanced_marker_icons.dart)、地图点击、相机动画、lite mode 等全部功能演示;对应平台层的单元测试位于 test/google_maps_flutter_ios_test.dart,原生 Swift 测试位于 example 的ios/RunnerTests(如 HeatmapControllerTests.swift、MarkerControllerTests.swift、PolygonControllerTests.swift 等),可作为接入与二次开发时的参考。
六、小结
google_maps_flutter_ios_sdk9是 Google Maps SDK 9.x 的 iOS 定向实现,通过implements: google_maps_flutter以联邦插件方式替换默认 iOS 实现;- 使用它只需在
pubspec.yaml显式添加依赖,Dart 代码零改动; - 必须配置 API Key(
GMSServices.provideAPIKey)并将最低 iOS 版本提升到15.0; - iOS 端热力图基于
GMUHeatmapTileLayer,因此dissipating、maxIntensity不支持,其余表格中列出的选项均可用; - 官方建议包作者只依赖
google_maps_flutter主包,把 SDK 版本选择权留给应用开发者。
【免费下载链接】packagesA collection of useful packages maintained by the Flutter team项目地址: https://gitcode.com/GitHub_Trending/pac/packages
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考