• Location


    #import "ViewController.h"
    #import <CoreLocation/CoreLocation.h>
    
    #define isIOS(version) ([[UIDevice currentDevice].systemVersion floatValue] >= version)
    
    @interface ViewController ()<CLLocationManagerDelegate>
    {
        CLLocation *_lastLocation;
    }
    /** 位置管理者 */
    @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(isIOS(8.0))
            {
                // 请求前台定位授权
                // 默认情况下, 只能在前台获取用户位置
                // 如果想要获取后台位置, 需要勾选后台模式 location updates , 但是会出现蓝条
                        [_locationM requestWhenInUseAuthorization];
                
                // 如果在iOS9.0+想要在前台授权模式下, 在后台获取用户位置, 我们需要额外的设置以下属性为YES
                if (isIOS(9.0)) {
                    _locationM.allowsBackgroundLocationUpdates = YES;
                }
                
                // 请求前后台定位授权
                // 默认在前后台都可以获取用户位置信息, 无论是否勾选后台模式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];
    
        //         kCLLocationAccuracyBestForNavigation // 最适合导航
        //         kCLLocationAccuracyBest; // 最好的
        //         kCLLocationAccuracyNearestTenMeters; // 附近10米
        //         kCLLocationAccuracyHundredMeters; // 100米
        //         kCLLocationAccuracyKilometer; // 1000米
        //         kCLLocationAccuracyThreeKilometers; // 3000米
        // 请求一次位置信息
        // 注意 不能与startUpdatingLocation 一起使用
        if(isIOS(9.0))
        {
    
    //        [self.locationM requestLocation];
        }
        
    }
    
    
    #pragma mark -CLLocationManagerDelegate
    // 当获取到用户位置信息时调用
    // manager : 位置管理者
    // locations: 位置数组 按时间进行排序, 如果想要拿到最新的位置, 直接拿最后一个
    // id+泛型 is kind of
    -(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations
    {
        
        // coordinate : 经纬度坐标
        // altitude : 海拔
        // horizontalAccuracy : 如果是负数, 代表当前位置不可用
        // course : 航向(0---359.0)
        // distanceFromLocation : 计算两个点之间的物理距离
        
        // 判断当前位置是否可用
        
        CLLocation *location = [locations lastObject];
        if(location.horizontalAccuracy < 0)
            return;
        
        // 场景演示:打印当前用户的行走方向,偏离角度以及对应的行走距离,
        // 例如:” 北偏东  30度  方向,移动了 8 米”
        // 1. 确定航向
        NSString *angleStr;
        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 substringToIndex:1];
        }
        
        
        // 确定行走了多少米
        double distance = 0;
        if (_lastLocation) {
            distance = [location distanceFromLocation:_lastLocation];
        }
        _lastLocation = location;
       // 例如:” 北偏东  30度  方向,移动了 8 米”
        NSString *noticeStr;
        if (angle == 0) {
            noticeStr = [NSString stringWithFormat:@"正%@方向, 移动了%f米", angleStr, distance];
        }else
        {
            noticeStr = [NSString stringWithFormat:@"%@%zd方向, 移动了%f米", angleStr, angle, distance];
        }
        
        
        NSLog(@"%@", noticeStr);
        
        
    //    NSLog(@"定位到了--%@", location);
        
        // 一般我们开发中, 获取到用户位置信息之后, 做一些业务逻辑操作
        // 针对于定位一次的情况, 可以在定位到之后 停止获取用户位置
    //    [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:]
    //                if([[UIApplication sharedApplication] openURL:<#(NSURL *)#>])
                    
                }else
                {
                    NSLog(@"定位服务关闭");
                }
                break;
            }
            case kCLAuthorizationStatusAuthorizedAlways:
            {
                 NSLog(@"前后台定位授权");
                break;
            }
            case kCLAuthorizationStatusAuthorizedWhenInUse:
            {
                NSLog(@"前台定位授权");
                break;
            }
                
            default:
                break;
        }
        
    }
    
    // 定位失败调用
    -(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
    {
        NSLog(@"定位失败");
    }
    
    @end
    

      

  • 相关阅读:
    2019-2020-1 20199304《Linux内核原理与分析》第四周作业
    2019-2020-1 20199304《Linux内核原理与分析》第三周作业
    第二周测试
    2019-2020-1 20199304《Linux内核原理与分析》第二周作业
    2019-2020-1 20199304《Linux内核原理与分析》第一周作业
    2019-2020-1 20199310《Linux内核原理与分析》第六周作业
    2019-2020-1 20199310《Linux内核原理与分析》第五周作业
    2019-2020-1 20199310《Linux内核原理与分析》第四周作业
    2019-2020-1 20199310《Linux内核原理与分析》第三周作业
    2019-2020-1 20199310《Linux内核原理与分析》第二周作业
  • 原文地址:https://www.cnblogs.com/yedayi/p/5137682.html
Copyright © 2020-2023  润新知