首先对于定位功能实现的问题,详见这幅帖子,超级全面详细:【iOS】7.4 定位服务->2.1.2 定位 - 官方框架CoreLocation: CLLocationManager(位置管理器)bash
iOS定位权限自从iOS8以后就改动不少,出于对用户隐私方面来讲,若是要调用GPS模块,就必须通过用户肯定,体如今应用弹窗让用户选择。须要在info.plist文件添加3个受权app
在iOS11时,Privacy - Location Always and When In Use Usage Description表示始终容许,Location Always Usage Description在功能上被降级为为“应用使用期间”。
复制代码
若是a,b两项添加到plist里,受权提示有2个选择项框架
那么当咱们容许应用使用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才会用到
对于一些运动类、导航类App,可能计时应用退到了后台也要获取用户的位置信息,该功能的实现咱们姑且称为:后台定位。
首先,在TARGETS->Capabilities->Background Modes中,开启开关,而且Location updates选项勾选上。
- (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;
}
}
复制代码
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];
复制代码
详见代码注释。
此表早已一应俱全,望各位施主早日参透
告辞!