iOS CLLocationManager定位

声明

因为苹果在不允许使用第三方库进行定位,即使是百度地图的定位也是在苹果API的基础上进行了封装,所以学习下iOS中定位的功能还是有必要的

CoreLocation框架

  • CLLocationManager是一个非常重要的对象

各系统版本的前台跟后台访问权限

  • iOS8之前
    如果想要定位需要在plist文件中位置key Privacy - Location Usage Description(NSLocationUsageDescription),默认只在前台定位,如果想开启后台定位需要在开启后台模式
iOS CLLocationManager定位_第1张图片
717775-cc91e37a8c114e7a.png
  • iOS8+
    iOS 8.0开始,苹果进一步加强了对用户隐私的保护
    当APP想访问用户的隐私信息时,系统不再自动弹出一个对话框让用户授权
    我们需要调用iOS 8.0的API,主动请求用户授权

  • (void)requestAlwaysAuthorization // 请求允许在前后台都能获取用户位置的授权

  • (void)requestWhenInUseAuthorization // 请求允许在前台获取用户位置的授权

注意:务必在info.plist文件中配置对应的键值, 否则以上请求授权的方法不生效
● NSLocationAlwaysUsageDescription : 允许在前后台获取GPS的描述
● NSLocationWhenInUseDescription : 允许在前台获取GPS的描述

注意: 如果是前台定位权限,但是开启了后台模式,在后台也是可以定位的,但是屏幕的上边会有蓝条,提示用户是哪个应用在定位

  • iOS 9
    如果想要在后台定位,除了配置NSLocationAlwaysUsageDescription(前后台定位)外,还需要手动设置allowsBackgroundLocationUpdates = YES, 否则 后台不会定位
#pragma mark - CLLocationManager懒加载
- (CLLocationManager *)lM
{
    if (!_lM) {
        // 1. 创建位置管理者
        _lM = [[CLLocationManager alloc] init];
        // 1.1 代理, 通知, block
        _lM.delegate = self;
        
        _lM.desiredAccuracy = kCLLocationAccuracyBest;
        
        if([[UIDevice currentDevice].systemVersion floatValue] >= 8.0)
        {
            
            [_lM requestAlwaysAuthorization];
        }
        // 允许后台获取用户位置(iOS9.0)
        if([[UIDevice currentDevice].systemVersion floatValue] >= 9.0)
        {
            // 一定要勾选后台模式 location updates 否者程序奔溃
            _lM.allowsBackgroundLocationUpdates = YES;
        }

    }
    return _lM;
}
注意:只要是想后台获取用户的位置,就必须开启后台模式 项目->TARGETS->Capabilities-> Background Modes 勾线 Location updates

CLLocationManager的一些属性

           kCLLocationAccuracyBestForNavigation // 最适合导航
           kCLLocationAccuracyBest; // 最好的
           kCLLocationAccuracyNearestTenMeters; // 10m
           kCLLocationAccuracyHundredMeters; // 100m
           kCLLocationAccuracyKilometer; // 1000m
           kCLLocationAccuracyThreeKilometers; // 3000m
// 设置定位的精确度
@property(assign, nonatomic) CLLocationAccuracy desiredAccuracy;

//  每隔多米定位一次 eg._lM.distanceFilter = 30;
@property(assign, nonatomic) CLLocationDistance distanceFilter;

CLLocationManagerDelegate

#pragma mark - CLLocationManagerDelegate
// 用户的位置更新之后调用
-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    /*
     经纬度
    @property(readonly, nonatomic) CLLocationCoordinate2D coordinate;
     海拔
    @property(readonly, nonatomic) CLLocationDistance altitude;
     航向
    @property(readonly, nonatomic) CLLocationAccuracy course;
     速度
    @property(readonly, nonatomic) CLLocationSpeed speed
    */
    CLLocation *location = locations.firstObject;
    NSLog(@"%f", location.coordinate.longitude);
}

// 授权状态发生改变时调用
// 第一次弹出请求定位权限会执行该代码块 用户如果点击 "不允许"  执行"定位开启,但被拒", 若点击 "允许" 执行 获取前后台定位授权 或者 获取前后台定位授权 如果在设置 设置隐私 定位服务 "永不" 则执 "行定位开启,但被拒"
// 注意:在设置点击了"永不"之后不返回应用在切换后台跟前台选项是不会执行该代理方法的 当返回应用之后 才会对做出的改变执行代理方法
// 关闭定位服务会执行 定位关闭,"不可用" 系统默认弹出弹框 提示用户去设置中打开定位服务选项
- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
    switch (status) {
            // 用户还未决定
        case kCLAuthorizationStatusNotDetermined:
        {
            NSLog(@"用户还未决定");
            
            break;
        }
            // 访问受限
        case kCLAuthorizationStatusRestricted:
        {
            NSLog(@"访问受限");
            break;
        }
            // 定位关闭时和对此APP授权为never时调用
        case kCLAuthorizationStatusDenied:
        {
            // 定位是否可用(是否支持定位或者定位是否开启)
            if([CLLocationManager locationServicesEnabled])
            {
                NSLog(@"定位开启,但被拒");
            }else
            {
                NSLog(@"定位关闭,不可用, 请在设置中打开定位服务选项");
            }
            //            NSLog(@"被拒");
            break;
        }
            // 获取前后台定位授权
        case kCLAuthorizationStatusAuthorizedAlways:
            //        case kCLAuthorizationStatusAuthorized: // 失效,不建议使用
        {
            NSLog(@"获取前后台定位授权");
            break;
        }
            // 获得前台定位授权
        case kCLAuthorizationStatusAuthorizedWhenInUse:
        {
            NSLog(@"获得前台定位授权");
            break;
        }
    }
}

你可能感兴趣的:(iOS CLLocationManager定位)