一、概述
由于迩来在开发跑步干系的功能,涉及到舆图定位功能,因此需要申请定位权限,之前APP中有定位需要,但因之前未过细的研究授权模式的设置,导致在开发跑步功能时产生了从未遇到的非常题目。
二、遇到的题目
题目形貌:初次安装APP,授权定位权限为WhenInUse利用期间定位定位,然后开启跑步,此时吸取定位回调,将APP切入背景等候3-5秒钟后,发现定位回调不再继续回调给APP,此时将APP返回前台,将规复定位回调,可吸取到定位效果数据。然后再将APP切回背景,这时会再次弹出定位模式选择弹窗,内容为”保持仅利用期间“和”更改为始终允许“。
定位发生错误Error Domain=com.baidu.location.locationerrordomain Code=2 "手机不允许定位,请确认用户授予定位权限大概手机是否打开定位开关" UserInfo={NSLocalizedDescription=手机不允许定位,请确认用户授予定位权限大概手机是否打开定位开关}注:此时定位模式被切换到whenInUse利用期间定位模式,前背景定位功能可正常利用
- 选择”更改为始终允许“:
此时定位模式被切换到Always始终定位模式,前背景定位功能可正常利用
- 题目的思考:
颠末对代码实现的观察发现,启动时申请定位权限时利用的requestAlwaysAuthorization,而不是requestWhenInUseAuthorization,固然两者弹出的体系弹窗类似,但是利用流程上是有区别的。由于我们的APP之前利用了Always申请始终定位权限,固然在初次弹窗是选择了”利用APP时允许“但是我们在打印授权状态时是kCLAuthorizationStatusAuthorizedAlways始终定位状态,这和我们选择的”利用APP时允许“初志有所差别。那怎样精确申请定位模式呢?
三、定位基础
体系全局定位开关,确定用户是否启用了位置服务,假如返回NO,需要提示用户到设置隐私中开启定位服务。
- @property (nonatomic, readonly) CLAuthorizationStatus authorizationStatus
返回应用步伐当前定位授权状态
typedef NS_ENUM(int, CLAuthorizationStatus) { kCLAuthorizationStatusNotDetermined = 0, // 用户未授权,即还未弹出OS的授权弹窗 kCLAuthorizationStatusDenied, // 用户拒绝定位权限,包罗拒绝App大概全局开关关闭 kCLAuthorizationStatusRestricted, // 定位服务受限,该状态位用户无法通过设置页面举行改变 kCLAuthorizationStatusAuthorizedAlways, // 始终定位,即背景定位 kCLAuthorizationStatusAuthorizedWhenInUse, // App利用的时间,允许定位 kCLAuthorizationStatusAuthorized, // iOS8.0之后已经被废弃};
- @property (nonatomic, readonly) CLAccuracyAuthorization accuracyAuthorization
返回应用步伐当前定位的准确度
typedef NS_ENUM(NSInteger, CLAccuracyAuthorization) { CLAccuracyAuthorizationFullAccuracy, //精准定位 CLAccuracyAuthorizationReducedAccuracy, // 暗昧定位};
- @property(weak, nonatomic, nullable) id<CLLocationManagerDelegate> delegate;
定位的署理实例,定位状态的变革会在CLLocationManagerDelegate的方法中回调
- @property(assign, nonatomic) BOOL pausesLocationUpdatesAutomatically
指定定位是否会被体系自动停息,默认是YES
- @property(assign, nonatomic) BOOL allowsBackgroundLocationUpdates
是否允许背景定位,默认是NO
- requestWhenInUseAuthorization
申请利用期间定位模式,下面会具体解释
- (void)requestAlwaysAuthorization
申请始终定位模式,下面会具体解释
四、利用期间定位模式
- 需要在Info.plist中设置NSLocationWhenInUseUsageDescription;
- 调用方法requestWhenInUseAuthorization申请利用期间定位模式,必须在status = kCLAuthorizationStatusNotDetermined的时间,调用才会出现体系弹窗,否则无响应;
- APP必须在前台运行时才会表现体系弹窗
- 体系弹窗选项:
选项授权利用App时允许APP利用时授权,不会失效status = WhenInUse允许一次暂时授权,授权后status = WhenInUse ,下次再次启动App时授权会失效 status = notDetermined不允许拒绝授权,不允许授权请求status = Denied
- 当应用步伐在前台开启正常利用时定位权限后,假如在Xcode中开启背景定位革新的本领,定位服务仍旧可以在背景继续运行;
- 当应用步伐切换到具有背景位置更新服务的背景时,体系会在状态栏中表现蓝色位置服务指示器,表现定位仍在举行中;
在iOS 16及更高版本中,自动跟踪用户位置或迩来启用核心位置的应用步伐会在Control Center中表现一个指示器。
五、始终定位模式
- 需要在Info.plist中设置NSLocationAlwaysAndWhenInUseUsageDescription、NSLocationWhenInUseUsageDescription假如需要支持 iOS10 的话需要设置 NSLocationAlawaysUsageDescription;
- 可以在授权状态为notDetermined和whenInUse时可调用requestAlwaysAuthorization;
- 体系对requestAlwaysAuthorization 方法的调用是有一定的限定的,当APP调用此方法后,在继续进一步调用是无响应的,也就是说不可以一连调用;
- 授权方式
A、 先获取"利用期间定位"模式后,再申请"始终定位"权限
获取Always权限前应用步伐需要先获取到whenInUse权限,然后再请求Always授权。
1、假如APP在获取whenInUse权限后,立刻调用requestAlwaysAuthorization方法,体系会立刻提示用户是否授权Always权限或保持whenInUse权限。
2、假如用户选择”仅允许一次“授权后,则体系会忽略requestAlwaysAuthorization方法的任何调用,此时属于暂时授权状态。
选项授权保持仅利用期间定位权限将继续保持为利用期间定位,署理未收到任何回调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 = Denied2、第二次弹窗的机遇:
- 当体系预备向APP转达的事故需要authorizedAlways权限时;
- 假如APP处于暂时”始终“定位状态时;
- 当APP进入背景进入非活泼状态挂起时;
选项授权保持仅利用期间体系将授权由暂时”始终“更改为”利用期间“,代分析收到状态变革事故,status = WhenInUse更改为始终允许移除暂时”始终”定位权限,变为“始终”授权状态,署理不会会收到状态变革回调,status = authorizedAlways注:假如用户在提示出现后做出选择,并选择允许“始终”权限,则位置事故将发送到您的应用步伐。
六、确定应用需要的授权限
A、应用步伐的定位授权状态决定了其是否需要及何时吸取定位事故:
- When In Use(APP利用期间定位)
您的应用步伐可以在利用中利用全部位置服务并吸取事故。一般来说,假如iOS应用步伐位于前台或在背景运行,并且背景位置利用指示器已启用,则视为正在利用。
- Always(APP总是定位)
您的应用步伐可以利用全部位置服务并吸取事故,纵然用户不知道您的应用步伐正在运行。假如你的应用步伐未运行,体系将启动你的应用步伐并转达事故。
- “利用期间定位”是首选模式
B、尽大概的请求授权利用“利用期间定位”模式,此模式具有强大的功能,允许您的应用步伐:
1、在用户利用应用步伐时访问全部可用的位置服务。假如用户克制利用你的应用步伐,任何未完成的请求都将挂起,直到用户规复利用你的应用步伐为止,才会规复定位服务
2、假如您在Xcode项目中启用了背景位置更新,纵然在应用步伐进入背景后,也可以继续获取位置更新。
3、利用位置关照触发器启动。假如您的应用步伐可以依赖用户的交互,请设置UNLocationNotificationTrigger,以在用户进入干系地区时关照用户。当用户点击关照时,体系启动应用步伐,使其有资格吸取位置事故。此方法允许用户在干系时刻决定是否与您的应用步伐共享其位置。
C、当应用步伐授权“利用期间定位”时,怎样确定应用步伐正在利用后定位?
1、当应用步伐在前台运行时;
2、在应用步伐离开前台后进入后的几秒钟内,您的应用步伐将有一个短的宽时间限期来完成用户启动的任何当前位置使命;
3、当应用步伐表现背景位置利用指示器(showsBackgroundLocationIndicator)时。在iOS上,指示灯是屏幕顶部的蓝色条或小球;
D、请求"始终"授权:
在以下情况下,您大概需要请求始终授权:
1、您的应用步伐实行自动使命,在此期间大概会不方便或不需要的表现提示;
2、你的应用步伐记载了一天中的很多位置,例如日记应用步伐。用户大概更倾向于允许始终授权,以便您的应用步伐纵然在未利用时也可以记载位置,而无需提示用户;
请记取,请求授权并不能包管你的应用步伐会收到授权。假如您请求“始终定位”授权,则用户可以选择在利用时授予您的应用步伐授权。您必须始终预备幸亏利用授权时运行。
注:假如您的应用步伐已经授权“利用时定位”授权,您可以稍后单独请求Always authorization。然而,应用步伐大概只发出一个始终授权请求。
七、竣事语
颠末分析和验证试验,确定在我的APP中定位回调非常题目是由于请求授权方式利用错误,优先利用When In Use定位模式,然后在需要利用Always”定位权限的位置再申请权限。当APP得到定位模式被用户选择为“When In Use”时,进入背景观察左上角是否有定位指示器(蓝色图标),存在的话可以确定当前定位服务正常。假如选择Always暗昧,那么屏幕左上角会表现定位图标。
官方文档 |