您的位置:首页 > 移动开发 > IOS开发

IOS -- iOS 8 CoreLocation 中状态栏(StatusBar)的细节问题

2015-09-18 10:40 471 查看
转载至 https://imethan.com/2015/01/23/guan-yu-ios-8-corelocation-de-xie-xi-jie/
iOS 8 发布以后,CoreLocation 变得复杂了些:

授权类型变成了:永不(Never)使用应用程序期间(WhenInUsing)始终(Always)
增加 WhenInUse 状态指示条:



增加 Always 不定期用户提示:



其他新特性如 CLVisit,此处暂不涉及;


细节1:授权文案配置

上述的两种授权方式,在 Info.plist 中分别对应了一个文案配置,用来在请求位置权限时告知用户“我们为什么要使用地理位置”:



如果调用获取授权 API 的时候没有配置对应的文案,系统不认做任何事情; 如果 App 只配置了其中一项,那么获取授权之后,在系统的隐私配置中只能看到“永不(Never)”和已配置的选项可选;

应用可以根据实际需要在 Info.plist 中配置,例如地图类 App 通常只需配置 Always,购物类通常只需要配置 WhenInUse;如果觉得选项不够用,仍可以在发布的新版本中添加其他选项配置;

如果两种选项都有配置,App 便可以根据实际需要请求 WhenInUse 或 Always 权限,但需要注意下一个细节 获取授权的顺序


细节2:获取授权的顺序

关于应用获取用户授权的两种方式,苹果官方文档关于 requestAlwaysAuthorization 的说明是这样的:

If the current authorization status is anything other than kCLAuthorizationStatusNotDetermined, this method does nothing and does not call the locationManager:didChangeAuthorizationStatus: method.

大意是指,当前授权状态不是“未知(kCLAuthorizationStatusNotDetermined)”时,调用 requestAlwaysAuthorization 不会做任何事情,也不会回调 locationManager:didChangeAuthorizationStatus: 代理方法;

但实际情况是:

当前状态为 WhenInUse(kCLAuthorizationStatusAuthorizedWhenInUse) 时,请求 requestAlwaysAuthorization 授权用户仍会收到提示是否授权 Always,并回调所有 CLLocationManager 实例的 delegate;

反之,如果先请求了 Always 授权,再请求 WhenInUse 则不会发生任何事;

所以,如果分散在不同工程中使用的 CLLocationManager,不注意这个细节,有可能出现两次请求授权的提示,结果不太友好;

两次授权,除了用户体验不好,还可能会导致回调逻辑的错误,请看下面这个细节;


细节3:请求代理授权回调

例如这段代码:
@implementation AnotherLocation
- (instancetype)init
{
...
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = (id<CLLocationManagerDelegate>)self;
[self.locationManager requestWhenInUseAuthorization];
[self.locationManager startUpdatingLocation];
...
}
- (void)locationManager:(CLLocationManager *)manager
didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
switch (status) {
case kCLAuthorizationStatusAuthorized:
NSLog(@"kCLAuthorizationStatusAuthorized");
[self.locationManager startUpdatingLocation];
break;
...
}
}
@end


`

如果在你实例里有一些自己的逻辑,比如状态回调回来时去启动位置更新,这时候请注意,如果还有其他 CLLocationManager 实例也在请求用户授权,并且导致 AuthorizationStatus 变化的时候,所有 CLLocationManager 的 delegate 方法都会被回调,如果没有关闭逻辑,后果可能很严重;

像上一点说的,有可能在一个应用中出现两次授权请求的情况,并导致这段代码逻辑被执行两次;具体表现就是,回调中的 startUpdatingLocation 执行后,获取完地理位置正常关闭后,又被调用了一次,这就导致应用一直在获取用户地理位置,状态条上的定位箭头一直存在

在没有开启应用 Backgroud Mode 的情况,压入后台后,获取地理位置也就自动被系统回收了,但不幸的是,具备 Background Mode 能力后,压入后台也能一直更新地理位置了,这可能导致用户电量损耗加快,而且出现下面所说的 WhenInUse蓝色状态提示条


细节4:Backgournd Mode + WhenInUse

App 的 Background Mode 有很多种,其中一种是在后台获取或发起定位的能力,这种能力一般用在导航、地理围栏等应用场景;

根据苹果官网文档介绍:

WhenInUse 是指应用只能在应用前台周期内可以发起地理位置更新,并不是说只能在应用使用中才能获取到地理位置更新:

If the user grants “when-in-use” authorization to your app, your app can start most (but not all) location services while it is in the foreground.
(Apps cannot use any services that automatically relaunch the app, such as region monitoring or the significant location change service.) When started in the foreground, services continue to run in the background if your app has enabled
background location updates
in the Capabilities tab of your Xcode project. Attempts to start location serviceswhile your app is running in the background will fail.

所以,虽然在大部分场景里,请求的是 WhenInUse 权限,但由于具备 Background Mode 并压入后台后,如果不及时 Stop 掉地理位置更新,应用将一直再后台存活着,并且一直接收系统 Deliver 过来的 Location updates;

由于地理位置数据的敏感性,当应用只有 WhenInUse 权限却仍在后台获取地理位置更新时,系统会弹出蓝色指示条:



The system displays a location-services indicator in the status bar when your app moves to the background with active location services.

这个状态条也会让用户紧张;


细节5:Always 二次确认

有了 Always 权限以后,便可以在任何时候启用地理位置服务,苹果为了用户隐私考虑,开启 Background Mode 的应用在后台持续获取地理位置变化一段时间后,会再次以 Alert 的方式让用户再次确认是否继续让应用在后台获取位置:



这样也会造成用户的担忧,使用 Always 前最好明确告知用户;


最后

地理位置信息对用户来说是相当敏感的隐私数据,使用时必须明确使用场景,尽量不要让用户对钱包产生不信任;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: