Google Maps当前位置显示错误,求排查问题原因
Google Maps定位标记与真实位置不匹配的问题排查
看起来你在集成Google Maps定位时遇到了位置偏差的问题,我来帮你梳理下代码里的几个关键问题:
你的原始代码存在的问题:
self.locationManger.requestWhenInUseAuthorization() self.locationManger.requestAlwaysAuthorization() var currentlocation: CLLocation! if (CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorizedWhenInUse || CLLocationManager.authorizationStatus() == CLAuthorizationStatus.authorized){ currentlocation = locationManger.location } let camera = GMSCameraPosition.camera(withLatitude: currentlocation.coordinate.latitude, longitude: currentlocation.coordinate.longitude, zoom: 15) mapView.camera=camera mapView.isMyLocationEnabled = true mapView.settings.myLocationButton = true mapView.padding = UIEdgeInsets(top: 0, left: 0, bottom: 90, right: 0)
权限请求逻辑混乱
你同时调用了requestWhenInUseAuthorization()和requestAlwaysAuthorization(),系统只会响应最后一次请求;而且你在发起请求后立刻检查授权状态——这时候用户可能还没来得及点击授权弹窗,locationManger.location大概率返回的是旧的缓存位置,甚至是nil,直接赋值会导致地图定位到错误的位置。没有等待实时位置更新
CLLocationManager的location属性是缓存的位置数据,不是实时获取的最新位置。你需要通过代理方法监听位置更新事件,才能拿到准确的当前位置。授权状态枚举值过时
在iOS 14及以上版本,CLAuthorizationStatus.authorized已经被废弃,应该用CLAuthorizationStatus.authorizedAlways来判断始终授权的状态,旧的枚举值可能导致授权状态判断不准确。
修正后的代码示例
首先确保你的视图控制器遵守CLLocationManagerDelegate协议,然后按以下方式实现:
import UIKit import GoogleMaps import CoreLocation class MapViewController: UIViewController, CLLocationManagerDelegate { @IBOutlet weak var mapView: GMSMapView! private let locationManager = CLLocationManager() override func viewDidLoad() { super.viewDidLoad() // 设置位置管理器代理 locationManager.delegate = self // 根据业务需求选择一种权限,不要同时请求两种 locationManager.requestWhenInUseAuthorization() // 或者使用 locationManager.requestAlwaysAuthorization() // 设置最高定位精度,确保位置准确 locationManager.desiredAccuracy = kCLLocationAccuracyBest // 开始监听位置更新 locationManager.startUpdatingLocation() // 配置地图基础设置 mapView.isMyLocationEnabled = true mapView.settings.myLocationButton = true mapView.padding = UIEdgeInsets(top: 0, left: 0, bottom: 90, right: 0) } // 监听位置更新,获取最新的实时位置 func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { // 取数组最后一个元素,也就是最新的位置 guard let latestLocation = locations.last else { return } // 更新地图相机到当前位置 let camera = GMSCameraPosition.camera(withLatitude: latestLocation.coordinate.latitude, longitude: latestLocation.coordinate.longitude, zoom: 15) mapView.camera = camera // 如果只需要一次定位,可以停止更新节省电量 locationManager.stopUpdatingLocation() } // 处理授权状态变化 func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { switch status { case .authorizedWhenInUse, .authorizedAlways: // 授权成功后开始更新位置 locationManager.startUpdatingLocation() case .denied, .restricted: // 提示用户开启位置权限 let alert = UIAlertController(title: "权限提示", message: "需要开启位置权限才能显示当前位置", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "确定", style: .default)) present(alert, animated: true) default: break } } }
其他可能的排查点
- 定位精度设置:如果
desiredAccuracy设置得过低(比如kCLLocationAccuracyThreeKilometers),会导致位置偏差较大,建议设置为kCLLocationAccuracyBest或kCLLocationAccuracyNearestTenMeters。 - 缓存位置影响:如果之前的应用有缓存的旧位置,可能会先显示缓存数据,通过
startUpdatingLocation获取最新位置后就能覆盖缓存。 - 测试环境:如果是在模拟器测试,模拟器的位置是模拟的,建议用真机测试真实的定位效果。
内容的提问来源于stack exchange,提问作者mrs.bassim
相关产品推荐
相关产品推荐

