对iOS定位授权弹窗机制的理解

2022-06-08  本文已影响0人  喔牛慢慢爬

一、概述

由于最近在开发跑步相关的功能,涉及到地图定位功能,因此需要申请定位权限,之前APP中有定位需要,但因之前未细致的研究授权模式的配置,导致在开发跑步功能时产生了从未遇到的异常问题。

二、遇到的问题

问题描述:首次安装APP,授权定位权限为WhenInUse使用期间定位定位,然后开启跑步,此时接收定位回调,将APP切入后台等待3-5秒钟后,发现定位回调不再继续回调给APP,此时将APP返回前台,将恢复定位回调,可接收到定位结果数据。然后再将APP切回后台,这时会再次弹出定位模式选择弹窗,内容为”保持仅使用期间“和”更改为始终允许“。

  1. 选择”保持仅使用期间“:
    会报错误
定位发生错误Error Domain=com.baidu.location.locationerrordomain Code=2 
"手机不允许定位,请确认用户授予定位权限或者手机是否打开定位开关" 
UserInfo={NSLocalizedDescription=手机不允许定位,
请确认用户授予定位权限或者手机是否打开定位开关}

注:此时定位模式被切换到whenInUse使用期间定位模式,前后台定位功能可正常使用

  1. 选择”更改为始终允许“:
    此时定位模式被切换到Always始终定位模式,前后台定位功能可正常使用

三、定位基础

系统全局定位开关,确定用户是否启用了位置服务,如果返回NO,需要提示用户到设置隐私中开启定位服务。

返回应用程序当前定位授权状态

typedef NS_ENUM(int, CLAuthorizationStatus) {
      kCLAuthorizationStatusNotDetermined = 0,  // 用户未授权,即还未弹出OS的授权弹窗
      kCLAuthorizationStatusDenied, // 用户拒绝定位权限,包括拒绝App或者全局开关关闭
      kCLAuthorizationStatusRestricted, // 定位服务受限,该状态位用户无法通过设置页面进行改变
      kCLAuthorizationStatusAuthorizedAlways, // 始终定位,即后台定位
      kCLAuthorizationStatusAuthorizedWhenInUse, // App使用的时候,允许定位
      kCLAuthorizationStatusAuthorized, // iOS8.0之后已经被废弃
};

返回应用程序当前定位的精确度

typedef NS_ENUM(NSInteger, CLAccuracyAuthorization) {
    CLAccuracyAuthorizationFullAccuracy, //精准定位
    CLAccuracyAuthorizationReducedAccuracy, // 模糊定位
};

定位的代理实例,定位状态的变化会在CLLocationManagerDelegate的方法中回调

指定定位是否会被系统自动暂停,默认是YES

是否允许后台定位,默认是NO

申请使用期间定位模式,下面会详细解释

申请始终定位模式,下面会详细解释

四、使用期间定位模式

选项 授权
使用App时允许 APP使用时授权,不会失效status = WhenInUse
允许一次 临时授权,授权后status = WhenInUse ,下次再次启动App时授权会失效 status = notDetermined
不允许 拒绝授权,不允许授权请求status = Denied

在iOS 16及更高版本中,主动跟踪用户位置或最近启用核心位置的应用程序会在Control Center中显示一个指示器。

五、始终定位模式

选项 授权
保持仅使用期间 定位权限将继续保持为使用期间定位,代理未收到任何回调status = WhenInUse
更改为始终允许 定位权限将修改为始终定位,代理会收到状态变化回调status = authorizedAlways

当 status = notdetermined时,调用requestWhenInUseAuthorization,只有用户同意“使用App时允许”的情况下才有用,然后当 status = WhenInUse时,调用requestAlwaysAuthorization或系统查觉到APP需要”始终“定位时,会再次出现始终授权模式弹窗。

B、直接申请获取"始终定位"权限
如果APP在定位授权状态为notDetermined时,此时调用requestAlwaysAuthorization方法后,系统会出现两次弹窗。
1、第一次弹窗与申请”使用期间定位“权限时相同;但是选择”使用App时允许“意义有所不同

选项 授权
使用App时允许 APP获得临时的”始终“定位权限,status = authorizedAlways
允许一次 临时授权,授权后status = WhenInUse ,下次再次启动App时授权会失效 status = notDetermined
不允许 拒绝授权,不允许授权请求status = Denied

2、第二次弹窗的时机:

选项 授权
保持仅使用期间 系统将授权由临时”始终“更改为”使用期间“,代理会收到状态变化事件,status = WhenInUse
更改为始终允许 移除临时”始终”定位权限,变为“始终”授权状态,代理不会会收到状态变化回调,status = authorizedAlways

注:如果用户在提示出现后做出选择,并选择允许“始终”权限,则位置事件将发送到您的应用程序。

六、确定应用需要的授权限

A、应用程序的定位授权状态决定了其是否需要及何时接收定位事件:

请记住,请求授权并不能保证你的应用程序会收到授权。如果您请求“始终定位”授权,则用户可以选择在使用时授予您的应用程序授权。您必须始终准备好在使用授权时运行。

注:如果您的应用程序已经授权“使用时定位”授权,您可以稍后单独请求Always authorization。然而,应用程序可能只发出一个始终授权请求。

七、结束语

经过分析和验证试验,确定在我的APP中定位回调异常问题是因为请求授权方式使用错误,优先使用When In Use定位模式,然后在需要使用Always”定位权限的位置再申请权限。当APP得到定位模式被用户选择为“When In Use”时,进入后台观察左上角是否有定位指示器(蓝色图标),存在的话可以确定当前定位服务正常。如果选择Always模糊,那么屏幕左上角会显示定位图标。

官方文档

上一篇 下一篇

猜你喜欢

热点阅读