zoukankan      html  css  js  c++  java
  • iOS地图 -- 定位使用

    • iOS的定位服务用到的框架是#import <CoreLocation/CoreLocation.h>
    • 定位中用到的类是CLLocationManager

    一.iOS8.0之前的定位

    • 向用户描述授权的信息需要在info.plist中配以下key
    • 后台情况下开启定位服务需要进行如下图配置

    二.iOS8.0之后的定位(包含iOS8.0)

    • iOS8.0之后前台定位授权和后台定位授权需要调用下面对应的方法
      // 前台定位授权 官方文档中说明info.plist中必须有NSLocationWhenInUseUsageDescription键
      [_mgr requestWhenInUseAuthorization];

      或者

      // 前后台定位授权 官方文档中说明info.plist中必须有NSLocationAlwaysUsageDescription键
      [_mgr requestAlwaysAuthorization];
    • iOS9新特性-只开启前台定位时临时开启后台定位功能

      在之前的版本如果只开启了用户使用期间定位就无法后台定位. iOS9更加灵活的提供了属性可以再需要的时候临时开启后台定位.

      首先设置allowsBackgroundLocationUpdates属性为YES

      然后需要增加plist键值对: Required background modes : App registers for location updates

    三.版本不同的适配问题(两种方法)

    • 方法一:
      // 方法一:判断iOS版本号
          if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) {
      
              // 前台定位授权 官方文档中说明info.plist中必须有NSLocationWhenInUseUsageDescription键
              [_mgr requestWhenInUseAuthorization];
              // 前后台定位授权 官方文档中说明info.plist中必须有NSLocationAlwaysUsageDescription键
              [_mgr requestAlwaysAuthorization];
          }
    • 方法二:高大上的方法
      // 方法二:判断位置管理者能否响应iOS8之后的授权方法
          if ([_mgr respondsToSelector:@selector(requestAlwaysAuthorization)]) {
      
      //            // 前台定位授权 官方文档中说明info.plist中必须有NSLocationWhenInUseUsageDescription键
      //            [_mgr requestWhenInUseAuthorization];
              // 前后台定位授权 官方文档中说明info.plist中必须有NSLocationAlwaysUsageDescription键
              [_mgr requestAlwaysAuthorization];
          }

    三.其余细节问题

    • 位置管理者的精确度
      /**
           kCLLocationAccuracyBestForNavigation; --> 最适合导航
           kCLLocationAccuracyBest; --> 最好的
           kCLLocationAccuracyNearestTenMeters; --> 附近10米
           kCLLocationAccuracyHundredMeters; --> 100米
           kCLLocationAccuracyKilometer; --> 1000米
           kCLLocationAccuracyThreeKilometers; --> 3000米
           */
          // 设置定位所需的精度 枚举值 精确度越高越耗电
          self.mgr.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
    • 位置管理者的过滤器,没移动制定的距离定位一次
      // 每100米更新一次定位
          self.mgr.distanceFilter = 100;

    四.代理方法中获取定位到的位置信息

    • CLLocation类,这里通过练习来讲解一下这个类,类中包含了获取到的用户位置的信息
      • coordinate --> 坐标,经度和纬度
      • altitude --> 海拔
      • horizontalAccuracy --> 水平精度
      • verticalAccuracy -->垂直精度
      • course --> 航向
      • speed --> 速度
      • timestamp --> 时间戳
      • distanceFromLocation: --> 计算两个位置之间的距离
    • 练习要求: 打印:北偏东 30度方向 走了100米 位置管理者的懒加载在下方
      - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
      {
          CLLocation *location = [locations lastObject];
          // 打印:北偏东 30度方向 走了100米
      
          // 1.计算方向
          NSArray *arr = @[@"北偏东",@"东偏南",@"南偏西",@"西偏北"];
          int index = (int)(location.course / 90); // course航向
          NSString *direction = arr[index];
          // 2.计算度数
          int degree = (int)location.course % 90;
          if (degree == 0) {
              direction = [@"" stringByAppendingString:[direction substringToIndex:1]];
          }
          // 3.计算路程
          double distance = 0;
          if (self.preivousLoc) {
      
              distance = [location distanceFromLocation:self.preivousLoc]; // 计算两点之间的距离
          }
          self.preivousLoc = location;
          // 4.拼串
          NSString *result;
          if (degree != 0) {
      
              result = [NSString stringWithFormat:@"%@ %zd度方向 走了%f米",direction,degree,distance];
          }
          else {
      
              result = [NSString stringWithFormat:@"%@ 方向 走了%f米",direction,distance];
          }
          NSLog(@"%@",result);
      }

    五.代理方法中监听授权状态的改变

    // 代理方法中监听授权的改变,被拒绝有两种情况,一是真正被拒绝,二是服务关闭了
    - (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
    {
        switch (status) {
            case kCLAuthorizationStatusNotDetermined:
            {
                NSLog(@"用户未决定");
                break;
            }
            // 系统预留字段,暂时还没用到
            case kCLAuthorizationStatusRestricted:
            {
                NSLog(@"受限制");
                break;
            }
            case kCLAuthorizationStatusDenied:
            {
                // 被拒绝有两种情况 1.设备不支持定位服务 2.定位服务被关闭
                if ([CLLocationManager locationServicesEnabled]) {
                    NSLog(@"真正被拒绝");
                    // 跳转到设置界面
                    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;
        }
    }

    六.练习详细代码

    #import "ViewController.h"
    #import <CoreLocation/CoreLocation.h>
    
    @interface ViewController ()<CLLocationManagerDelegate>
    /** 位置管理者 */
    @property(nonatomic,strong) CLLocationManager *mgr;
    @end
    
    @implementation ViewController
    
    #pragma mark - 懒加载
    - (CLLocationManager *)mgr
    {
        if (_mgr == nil) {
            // 实例化位置管理者
            _mgr = [[CLLocationManager alloc] init];
            // 指定代理,代理中获取位置数据
            _mgr.delegate = self;
    
            // 兼容iOS8之后的方法
            // 方法一:判断iOS版本号
            if ([[UIDevice currentDevice].systemVersion doubleValue] >= 8.0) {
    
                // 前台定位授权 官方文档中说明info.plist中必须有NSLocationWhenInUseUsageDescription键
                [_mgr requestWhenInUseAuthorization];
                // 前后台定位授权 官方文档中说明info.plist中必须有NSLocationAlwaysUsageDescription键
                [_mgr requestAlwaysAuthorization];
            }
            // 方法二:判断位置管理者能否响应iOS8之后的授权方法
            if ([_mgr respondsToSelector:@selector(requestAlwaysAuthorization)]) {
    
    //            // 前台定位授权 官方文档中说明info.plist中必须有NSLocationWhenInUseUsageDescription键
    //            [_mgr requestWhenInUseAuthorization];
                // 前后台定位授权 官方文档中说明info.plist中必须有NSLocationAlwaysUsageDescription键
                [_mgr requestAlwaysAuthorization];
            }
          // 允许后台获取用户位置(iOS9.0)  
             if([[UIDevice currentDevice].systemVersion floatValue] >= 9.0)  {  
                 // 一定要勾选后台模式 location updates  
                 _lM.allowsBackgroundLocationUpdates = YES;  
             } 
        }
        return _mgr;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // 开启位置更新
        [self.mgr startUpdatingLocation];
    
        /**
         kCLLocationAccuracyBestForNavigation; --> 最适合导航
         kCLLocationAccuracyBest; --> 最好的
         kCLLocationAccuracyNearestTenMeters; --> 附近10米
         kCLLocationAccuracyHundredMeters; --> 100米
         kCLLocationAccuracyKilometer; --> 1000米
         kCLLocationAccuracyThreeKilometers; --> 3000米
         */
        // 设置定位所需的精度 枚举值 精确度越高越耗电
        self.mgr.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
        // 每100米更新一次定位
        self.mgr.distanceFilter = 100;
    }
    
    #pragma mark - CLLocationManagerDelegate
    
    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
    {
        NSLog(@"已经定位");
    }
    
    // 代理方法中监听授权的改变,被拒绝有两种情况,一是真正被拒绝,二是服务关闭了
    - (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
    {
        switch (status) {
            case kCLAuthorizationStatusNotDetermined:
            {
                NSLog(@"用户未决定");
                break;
            }
            // 系统预留字段,暂时还没用到
            case kCLAuthorizationStatusRestricted:
            {
                NSLog(@"受限制");
                break;
            }
            case kCLAuthorizationStatusDenied:
            {
                // 被拒绝有两种情况 1.设备不支持定位服务 2.定位服务被关闭
                if ([CLLocationManager locationServicesEnabled]) {
                    NSLog(@"真正被拒绝");
                    // 跳转到设置界面
                    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
  • 相关阅读:
    fatal error LNK1123: 转换到 COFF 期间失败:文件无效或损坏
    CI:模拟进化与遗传算法
    贝叶斯网络
    朴素贝叶斯模型
    概率与不确定性(乘法法则与贝叶斯法则)
    关于“启发式”搜索的一个形象解释
    Python 字符串与数字拼接报错
    无法启动此程序因为计算机中丢失 xxx.dll
    Python 以指定的概率选取元素
    验证码之SimpleCaptcha (二)
  • 原文地址:https://www.cnblogs.com/jiqiaochun/p/8548026.html
Copyright © 2011-2022 走看看