一、简介
- 从iOS8.0开始,苹果
进一步加强
了对用户隐私的保护
。- 当APP想访问用户的隐私信息时,系统
不再自动弹出
一个对话框让用户授权
- 当APP想访问用户的隐私信息时,系统
解决方案 : 主动请求用户授权
- 调用iOS8.0的API,
主动请求用户授权
// 请求允许在前后台都能获取用户位置的授权
- (void)requestAlwaysAuthorization
//请求允许在前台获取用户位置的授权
- (void)requestWhenInUseAuthorization
- 务必在
info.plist文件中配置
对应的键值,否则以上请求授权的方法不生效
NSLocationAlwaysUsageDescription: 允许在前后台获取GPS的描述
NSLocationWhenInUseDescription : 允许在前台获取GPS的描述
注意:
- iOS8.0+授权适配
- 两种适配方案:(通过系统版本号,通过对象是否响应方法)(配置info.list文件中对应的键值
- 1、请求前台定位授权
- 2、请求前后台定位授权
-
requestWhenInUseAuthorization 和 requestAlwaysAuthorization 区别
- (默认情况下:前者只有在APP前台时可以定位,后者可以在前后台进行定位)
- 勾选后台运行模式location后的变化(在9.0之前,前者后台依然可以定位,但会出现蓝条;后者不会出现蓝条;)
-
授权状态的变更,调用对应的代理方法
- 说明不同状态代表的含义,给予用户对应的提示
-
特别注意:
- 当定位服务被拒绝,
iOS8.0+
,要利用UIApplication的openUrl方法,进行跳转到设置界面,提示用户开启定位服务
- 当定位服务被拒绝,
二、实现定位步骤
1、前台定位
- 1.导入CoreLocation框架和对应的主头文件
#import <CoreLocation/CoreLocation.h>
- 2.创建CLLcationManager对象,并设置代理请求前台定位授权,并配置KEY
- 3.调用CLLcationManager对象的startUpdatingLocation方法进行更新用户位置
[_locationM startUpdatingLocation];
- 4.实现代理方法,接收位置参数
-(void)locationManager:(nonnull CLLocationManager *)manager didUpdateLocations:(nonnull NSArray<CLLocation *> *)locations
2、后台定位
- 方案一:在APP处于
前台定位授权
场景下,勾选后台运行模式
update locations- 注意:如果APP处于后台,则会出现
蓝条
- 注意:如果APP处于后台,则会出现
- 方案二:请求
前后台定位授权
,并配置KEY- 不会出现蓝条
[_locationM requestAlwaysAuthorization];
![配置KEY.png](http:https://img.haomeiwen.com/i831339/6758a37fbf2aa629.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
## 三、基本实现
+ Info.plist文件中配置,进行前台/前后台定位,定位目的的配置
![定位目的的配置.png](http:https://img.haomeiwen.com/i831339/c7a92204cb8b0ff0.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
```objc
#import "ViewController.h"
#import <CoreLocation/CoreLocation.h>
@interface ViewController ()<CLLocationManagerDelegate>
/** 位置管理者 */
@property (nonatomic, strong) CLLocationManager *locationM;
@end
@implementation ViewController
#pragma mark -懒加载
-(CLLocationManager *)locationM
{
if (!_locationM) {
//1 创建位置管理者
_locationM = [[CLLocationManager alloc] init];
// 1.1 告诉外界位置的方案: 代理, block 通知
_locationM.delegate = self;
// 设置每隔多远定位一次(1次 111km/100m)
// 最新的位置距离上一次位置之间的距离大于100m, 才会通过代理告诉外界
// _locationM.distanceFilter = 100;
// kCLLocationAccuracyBestForNavigation // 最适合导航
// kCLLocationAccuracyBest; // 最好的
// kCLLocationAccuracyNearestTenMeters; // 附近10米
// kCLLocationAccuracyHundredMeters; // 100米
// kCLLocationAccuracyKilometer; // 1000米
// kCLLocationAccuracyThreeKilometers; // 3000米
// 定位精确度
// 定位精确度越高, 越耗电, 而且, 定位时间越长
_locationM.desiredAccuracy = kCLLocationAccuracyBest;
//**-------ios8.0+定位适配---------- */
if([[UIDevice currentDevice].systemVersion floatValue] >= 8.0)
{
// 请求前台定位授权
// 默认情况下, 只能在前台获取用户位置
// 如果想要获取后台位置, 需要勾选后台模式 location updates , 但是会出现蓝条
// [_locationM requestWhenInUseAuthorization];
// 请求前后台定位授权
// 默认在前后台都可以获取用户位置信息, 无论是否勾选后台模式locaiton updates, 而且不会出现蓝条
// 如果当前的授权状态!=用户为选择状态, 那么这个方法不会有效
[_locationM requestAlwaysAuthorization];
}
// 其它适配方案
// if([_locationM respondsToSelector:@selector(requestAlwaysAuthorization)])
// {
// [_locationM requestAlwaysAuthorization];
// }
}
return _locationM;
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// 2. 使用位置管理者, 开始获取用户位置
// 开发经验: start 开始某个服务 stop 停止某个服务
// 一旦调用了这个方法, 那么就会不断的获取用户位置信息, 然后告诉外界
// 默认情况,只能在前台获取用户位置信息, 如果我们想要在后台获取位置, 必须勾选后台模式 location updates
// 标准定位服务(基于gps/wifi/基站)
[self.locationM startUpdatingLocation];
// 监听重大位置的改变(基于基站进行定位 , 要求, 设备必须有电话模块)
// [self.locationM startMonitoringSignificantLocationChanges];
}
#pragma mark -CLLocationManagerDelegate
// 当获取到用户位置信息时调用
// manager : 位置管理者
// locations: 位置数组
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
NSLog(@"定位到了");
// 一般我们开发中, 获取到用户位置信息之后, 做一些业务逻辑操作
// 针对于定位一次的情况, 可以在定位到之后 停止获取用户位置
// [manager stopUpdatingLocation];
}
// 如果授权状态发生变化时,调用
// status : 当前的授权状态
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
switch (status) {
case kCLAuthorizationStatusNotDetermined:
{
NSLog(@"用户未决定");
break;
}
case kCLAuthorizationStatusRestricted:
{
NSLog(@"受限制");
break;
}
case kCLAuthorizationStatusDenied:
{
// 判断当前设备是否支持定位, 并且定位服务是否开启()
if([CLLocationManager locationServicesEnabled])
{
NSLog(@"定位开启,被拒绝");
// ios8,0- 需要截图提醒引导用户
// iOS8.0+
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if([[UIApplication sharedApplication] canOpenURL:url])
{
[[UIApplication sharedApplication] openURL:url];
}
}else
{
NSLog(@"定位服务关闭");
}
break;
}
case kCLAuthorizationStatusAuthorizedAlways:
{
NSLog(@"前后台定位授权");
break;
}
case kCLAuthorizationStatusAuthorizedWhenInUse:
{
NSLog(@"前台定位授权");
break;
}
default:
break;
}
}
@end
网友评论