iOS CLLocationManager的弹窗问题

iOS系统在请求定位权限时会弹窗提示。某些情况下,APP中的一些模块可能不需要主动引发弹窗但又需要获取定位数据。

使用iOS CLLocationManager时,系统会在请求定位权限时显示弹窗。下面以iOS 14系统为例说明。

何时会弹窗

iOS系统是否开启定位服务会影响弹窗效果。

  • 当系统定位服务开启后

执行以下请求定位权限方法时会弹窗:「允许“EASEAPI”使用您的位置?」

func requestWhenInUseAuthorization()
func requestAlwaysAuthorization()
func requestTemporaryFullAccuracyAuthorization(withPurposeKey purposeKey: String, completion: ((Error?) -> Void)? = nil)

直到用户主动选择授权方式,弹窗才会消失。

  • 当系统定位服务关闭后

除了执行以上几个请求权限方法,首次执行

func startUpdatingLocation()

时也会引发系统弹窗:打开“定位服务”来允许“EASEAPI”确定您的位置。用户主动选择后,弹窗消失。

如何避免弹窗

随着用户对隐私保护的重视,现在越来越多的APP要求收紧定位权限:当用户主动在界面上点击特定按钮时才弹窗,而不是一打开APP就弹窗。这就要求一些后台service的代码不应该触发弹窗,但同时还需要定位数据。那么可以先判断系统开启定位服务后,再执行startUpdatingLocation()。

if CLLocationManager.locationServicesEnabled {
    self.locationManager.startUpdatingLocation()
}

当然,如果不需要在didUpdateLocations回调方法实时获取最新的定位数据,完全也可以不执行startUpdatingLocation()。初始化self.locationManager后,在需要位置数据时,直接访问self.locationManager.location即可。

这和APP对CLLocationManager的实现有关。由于定位服务比较耗费资源,iOS系统实际上共用了一份定位数据,且总是以精度最高的desiredAccuracy来处理的。只要当前APP中其它CLLocationManager实例获取到定位信息,整个APP中所有的CLLocationManager实例都可以通过访问location属性获得最新的定位数据。

其他文章

iOS NSURLProtocol详解及使用陷阱
iOS URLSession Authentication Challenge及SSL Pinning
iOS Method Swizzling使用陷阱
CocoaPods Podfile and podspec configurations
iOS TestFlight的局限性及改进措施