• 快速入门:CoreLocation框架进行定位和iOS不同版本间定位的差异


    使用CoreLocation框架进行定位

    • 废话不多说,直接上干货

    1. iOS8之前的定位

    • 直接上代码,代码里面有详细的步骤
    #import "ViewController.h"
    // 0. 导入头文件
    #import <CoreLocation/CoreLocation.h>
    
    @interface ViewController () <CLLocationManagerDelegate>
    /** 位置管理者 */
    @property (nonatomic, strong) CLLocationManager *manager;
    @end
    
    @implementation ViewController
    - (CLLocationManager *)manager
    {
        if (!_manager) {
            // 1. 创建CLLocationManager
            _manager = [[CLLocationManager alloc] init];
            // 2. 设置代理
            _manager.delegate = self;
    
            // 每隔多少米定位一次
            _manager.distanceFilter = 100;
    
            /**
             kCLLocationAccuracyBestForNavigation // 最适合导航
             kCLLocationAccuracyBest; // 最好的精确度,仅次于kCLLocationAccuracyBestForNavigation
             kCLLocationAccuracyNearestTenMeters; // 附近10m
             kCLLocationAccuracyHundredMeters; // 100m
             kCLLocationAccuracyKilometer; // 1千米
             kCLLocationAccuracyThreeKilometers; // 3千米
             */
            // 设置定位精确度
            // 并不是精确度越高就越好,精确度越高,就越耗性能,越费电,要根据需求来设置精确度
            _manager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
        }
        return _manager;
    }
    
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        // 3.开始更新地址
        // 此处重点:一定要在info.plist文件中加上key:Privacy - Location Usage Description,value可以随便写
        [self.manager startUpdatingLocation];
    
    
    }
    
    #pragma mark - 实现CLLocationManagerDelegate代理方法
    // 4.实现代理方法
    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
    {
        CLLocation *location = [locations lastObject];
        NSLog(@"%@ -- %f", location.description, location.speed);
    }
    @end
    
    
    • 注意点:第三步出,一定要在info.plist文件中加上key:Privacy - Location Usage Description,如图所示:

    2.iOS8的定位

    • iOS8相对于之前的版本,苹果进一步加强了对用户隐私的保护。
      当APP想访问用户的隐私信息时,系统不再自动弹出一个对话框让用户授权
    • 解决方案:
      • (1)调用iOS 8.0的API,主动请求用户授权

        • -(void)requestAlwaysAuthorization // 请求允许在前后台都能获取用户位置的授权
        • -(void)requestWhenInUseAuthorization // 请求允许在前台获取用户位置的授权
      • (2)务必在info.plist文件中配置对应的键值, 否则以上请求授权的方法不生效
        NSLocationAlwaysUsageDescription : 允许在前后台获取GPS的描述
        NSLocationWhenInUseDescription : 允许在前台获取GPS的描述

    #import "ViewController.h"
    #import <CoreLocation/CoreLocation.h>
    
    @interface ViewController () <CLLocationManagerDelegate>
    /** 位置管理者 */
    @property (nonatomic, strong) CLLocationManager *manager;
    @end
    
    @implementation ViewController
    - (CLLocationManager *)manager
    {
        if (_manager == nil) {
            _manager = [[CLLocationManager alloc] init];
            _manager.delegate = self;
    
            // 采取前台定位
            // 1. 需要在info.plist文件中添加key:NSLocationWhenInUseUsageDescription
            // 2. 如果需要在后台继续定位,需要勾选后台模式,当程序进入后台后,会在最上方出现一个蓝条
    //        [_manager requestWhenInUseAuthorization];
    
            // 采用前后台定位
            // 1. 需要在info.plist文件中添加NSLocationAlwaysUsageDescription这个key
            // 2. 这种模式的后台定位,不需要勾选后台模式,也不会出现蓝条
            [_manager requestAlwaysAuthorization];
    
    
            // requestWhenInUseAuthorization和requestAlwaysAuthorization请求同时存在:
            // 1. requestWhenInUseAuthorization请求在前,会先弹出前台授权描述,第二次启动程序的时候,还会弹出前后台授权描述
            // 2. requestAlwaysAuthorization在前,只会弹出前后台授权描述,不会弹出前台授权描述.
        }
        return _manager;
    }
    
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
    {
        [self.manager startUpdatingLocation];
    
    }
    
    #pragma mark - <CLLocationManagerDelegate>
    /**
     *  更新定位
     *
     *  @param manager   位置管理器
     *  @param locations 定位的位置数组
     */
    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
    {
        NSLog(@"定位了");
    }
    
    

    3. iOS9 的定位

    • 在iOS9中,如果使用requestWhenInUseAuthorization,跟iOS8一样,不仅需要设置info.plist,如果想要在后台定位,也需要勾选后台模式,还需要设置allowsBackgroundLocationUpdates=Yes.同样也会出现蓝条
            _manager.allowsBackgroundLocationUpdates = YES;
    
    • iOS 9.0 可以单次请求用户位置:-(void)requestLocation
      • 作用是按照定位的精确度从低到高进行排序,逐个进行定位.如果获取到的位置不是精确度最高的那个,也会在定位超时后,通过代理告诉外界(必须实现代理的-locationManager:didFailWithError:方法, 不能与startUpdatingLocation方法同时使用)
    - (void)requestLocation
    -(void)locationManager:(nonnull CLLocationManager *)manager didUpdateLocations:(nonnull NSArray<CLLocation *> *)locations  // 成功调用
    -(void)locationManager:(nonnull CLLocationManager *)manager didFailWithError:(nonnull NSError *)error // 失败调用
    

    4. CLLocation

    • 以一个小的需求来学习CLLocation
    • 一个小需求:打印当前用户的行走方向,偏离角度以及对应的行走距离, 例如:”北偏东30度方向,移动了8米”
    /**
     *  代理方法: 更新定位
     *
     *  @param manager   位置管理器
     *  @param locations 定位的位置数组
     */
    - (void)locationManager:(nonnull CLLocationManager *)manager didUpdateLocations:(nonnull NSArray<CLLocation *> *)locations
    {
        // CLLocation常用属性
        // coordinate	(当前位置所在的经纬度)
        // altitude	(海拔)
        // speed	(当前速度)
        // course (航向)
    
        // -distanceFromLocation (获取两个位置之间的直线物理距离)
    
        CLLocation *location = [locations lastObject];
    
        // 1. 获取偏向角度
        NSString *angleStr = nil;
    
        switch ((int)location.course / 90) {
            case 0:
                angleStr = @"北偏东";
                break;
            case 1:
                angleStr = @"东偏南";
                break;
            case 2:
                angleStr = @"南偏西";
                break;
            case 3:
                angleStr = @"西偏北";
                break;
            default:
                angleStr = @"未知位置";
                break;
        }
    
        // 2. 偏移角度
        NSInteger angle = (int)location.course % 90;
        if (angle == 0) { // 表示正方向
            angleStr = [angleStr substringWithRange:NSMakeRange(0, 1)];
        }
    
        // 3. 移动了多少米
        double distance = 0;
        if (_oldLocation) {
            distance = [location distanceFromLocation:_oldLocation];
        }
        _oldLocation = location;
    
        // 4. 打印
        NSString *locationStr = [NSString stringWithFormat:@"%@%zd度方向,移动了%.2fm", angleStr, angle, distance];
        NSLog(@"%@", locationStr);
    }
    
    

    5.定位的其他补充

    • 授权状态
         kCLAuthorizationStatusNotDetermined = 0, // 用户未决定
    
         kCLAuthorizationStatusRestricted, // 受限制
    
         kCLAuthorizationStatusDenied, // 拒绝
    
         kCLAuthorizationStatusAuthorizedAlways NS_ENUM_AVAILABLE(NA, 8_0), // 永久授权
    
         kCLAuthorizationStatusAuthorizedWhenInUse NS_ENUM_AVAILABLE(NA, 8_0), // APP使用的时候授权
    
  • 相关阅读:
    开发工具 之 PowerDesigner 应用积累
    PowerDesigner 之 PDM建模
    开发工具 之 PowerDesigner
    LCD 和 LED 的区别?
    图像色彩空间YUV和RGB的差别
    ubuntu使用中的一些问题
    FFMPEG-数据结构解释(AVCodecContext,AVStream,AVFormatContext)
    Winform的多线程问题
    C#子线程更新UI控件的方法总结
    malloc(0)的问题
  • 原文地址:https://www.cnblogs.com/coderAlin/p/4753580.html
Copyright © 2020-2023  润新知