iOS 后台定位 蓝条问题

首先对于定位功能实现的问题,详见这幅帖子,超级全面详细:【iOS】7.4 定位服务->2.1.2 定位 - 官方框架CoreLocation: CLLocationManager(位置管理器)bash

1、开启定位权限的配置

iOS定位权限自从iOS8以后就改动不少,出于对用户隐私方面来讲,若是要调用GPS模块,就必须通过用户肯定,体如今应用弹窗让用户选择。须要在info.plist文件添加3个受权app

  • a. Privacy - Location When In Use Usage Description (应用使用期间),
  • b. Privacy - Location Always Usage Description(始终容许),
  • c. Privacy - Location Always and When In Use Usage Description(始终容许,iOS11新增)
在iOS11时,Privacy - Location Always and When In Use Usage Description表示始终容许,Location Always Usage Description在功能上被降级为为“应用使用期间”。
复制代码

若是a,b两项添加到plist里,受权提示有2个选择项框架

定位受权弹窗一
若是a,b,c 所有添加到plist里,受权提示有3个选择项

定位受权弹窗二

那么当咱们容许应用使用GPS获取位置信息以后,咱们在设置-隐私-定位服务 找到本身的应用点进去能够看到以下 upload-images.jianshu.io/upload_imag… ui

有三个选项: 1.永不 2.使用应用期间 3.始终。spa

  • 永不:不给定位权限
  • 使用应用期间:应用在前台运行状态才获取定位信息
  • 始终:包括应用在后台也能获取定位信息

通常状况下,在info.plist文件中,将以上三条都配置上.code

固然,有的状况下只需两个选择:cdn

  • 1.永不 2.使用应用期间
    info.plist只设置了NSLocationWhenInUseUsageDescription对象

  • 1.永不 2.始终blog

    info.plist只设置了NSLocationAlwaysUsageDescription和NSLocationAlwaysAndWhenInUseUsageDescription (今天在iPhone7 plus iOS12.1.4系统 怎么试都不显示定位选择弹框,不知道咋回事,大家能够尝试下,告知下我结果)。ip

通常除了导航、运动类App才会用到

2、实现后台定位

对于一些运动类、导航类App,可能计时应用退到了后台也要获取用户的位置信息,该功能的实现咱们姑且称为:后台定位。

首先,在TARGETS->Capabilities->Background Modes中,开启开关,而且Location updates选项勾选上。

第一步在info.plist文件中配置好了获取用户隐私权限后,第一次登入App,用户会收到一个定位受权弹窗。根据用户的选择状况,会走CLLocationManagerDelegate协议中的- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status方法。固然,也能够经过CLAuthorizationStatus status = [CLLocationManager authorizationStatus];获取当前用户选择的受权状态,而后进行判断作相应逻辑处理。通常处理以下:

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
    NSLog(@"定位: %d",status);
    switch (status) {
        case kCLAuthorizationStatusNotDetermined:
            NSLog(@"用户未作选择");//能够提示跳转到设置
            break;
        case kCLAuthorizationStatusRestricted:
            NSLog(@"定位被限制");
            break;
        case kCLAuthorizationStatusDenied:
            NSLog(@"用户拒绝获取定位");
            break;
        case kCLAuthorizationStatusAuthorizedAlways:
            //用户赞成永久访问定位
            [self.locationManager requestAlwaysAuthorization];
            break;
        case kCLAuthorizationStatusAuthorizedWhenInUse:
            //用户容许使用应用期间访问定位
            [self.locationManager requestWhenInUseAuthorization];
            break;
        default:
            break;
    }
}
复制代码

3、关于蓝条问题的产生机理和处理办法

这种蓝条问题的产生和解决。

CLLocationManager管理类的配置

_locationManager = [[CLLocationManager alloc] init];
    _locationManager.delegate = self;
    _locationManager.distanceFilter = 100;
    _locationManager.desiredAccuracy = kCLLocationAccuracyBest;

    if ([[UIDevice currentDevice] systemVersion].floatValue >= 8) {
        /*
         有这么一种说法
         若是两个请求受权的方法都执行了,会出现如下状况
         1.requestWhenInUseAuthorization写在前面,第一次打开程序时请求受权,若是勾选了后台模式,进入后台会出现蓝条提示正在定位。当程序退出,第二次打开程序时requestAlwaysAuthorization 会再次请求受权。以后进入后台就不会出现蓝色状态栏。
         2.requestAlwaysAuthorization写在前面, requestWhenInUseAuthorization写在后面,只会在第一次打开程序时请求受权,由于requestAlwaysAuthorization获得的受权大于requestWhenInUseAuthorization获得的受权
         */
        [_locationManager requestAlwaysAuthorization];
        [_locationManager requestWhenInUseAuthorization];
    }
    if ([[UIDevice currentDevice] systemVersion].floatValue >= 9) {
        /*
         allowsBackgroundLocationUpdates:是否容许后台定位,默认为NO,只在iOS9.0以后起做用。
         设为YES时,必须保证Background Modes 中的Location updates处于选中状态,不然会抛出异常。
         在用户选择仅在使用应用期间获取位置权限的状况下,当应用进入后台,手机桌面顶部是否出现蓝条,这句代码起着关键性做用。
         首先,这句代码仅在requestWhenInUseAuthorization状态下才起做用,不然不起做用。当设为YES,就是容许在requestWhenInUseAuthorization此状态下,即便App进入后台,可是没杀死,那么就依然能够后台定位。而且顶部给个蓝条闪烁,目的是在于实时提醒用户:你这个App一直在获取你的位置信息哟,若是你感到不须要继续获取了,就杀死该App吧!因此一直蓝条闪烁。
         当设置为NO,就是在requestWhenInUseAuthorization状态下,App进入后台,当即中止后台定位。
         */
        _locationManager.allowsBackgroundLocationUpdates = YES;
        /*
         requestLocation和startUpdatingLocation这两个方法很是相似,都会当即返回结果,将获取的定位信息传递给委托对象的locationManager:didUpdateLocations:消息。
         不一样点:
         startUpdatingLocation:能够持续获取定位。当设备移动的距离超过设定的distanceFilter属性值时,接收器会再次生成一条更新消息。
         requestLocation:只产生一次定位信息,在此以后定位服务就中止了。而且:当使用这个方法时,委托对象必需要实现locationManager:didUpdateLocations:和locationManager:didFailWithError:方法。
         */
        [_locationManager requestLocation];
    } else {
        [_locationManager startUpdatingLocation];
        
    }
复制代码

其实在上段代码注释中已经写得较清楚了。

  • 蓝条问题的产生前提:只在requestWhenInUseAuthorization这个状态下才会出现。

  • 蓝条出现的目的:由于用户选择的是仅在应用使用期间获取位置,因此当app进入后台后,系统将以蓝条闪烁的形式不断提醒用户:主人,某某App一直在后台获取你的位置权限哟,若是你不须要用到了,你就直接将该App杀死吧,否则挺耗电的,若是有须要就当我没说哈。

  • 蓝条出现与否的背后代码操控者:_locationManager.allowsBackgroundLocationUpdates = YES;若是不想出现蓝条,直接设置为NO,或者注释,由于默认为NO。

  • 另外,蓝条出现与否的另外一种说法:跟下面两句代码的执行顺序有关

[_locationManager requestAlwaysAuthorization];
        [_locationManager requestWhenInUseAuthorization];
复制代码

详见代码注释。

4、一张很经典的表格

此表早已一应俱全,望各位施主早日参透

告辞!

相关文章
相关标签/搜索