iOS开发-用户定位获取-CoreLocation的实际应用-CLLocationManger获取定位权限-CLLocation详细使用方式

iOS开发-用户定位获取-CoreLocation的实际应用-CLLocationManger获取定位权限-CLLocation详细使用方式iOS提供了两个框架用来定位以及地图显示。CoreLocation框架包含的类可以帮助设备确定位置和航向以及使用基于位置的有效信息。MapKit框架未定位提供了户用页面的支持(地图显示),里面包含了地图视图、卫星地图视图以及2D、3D混合视图,并且能够让开发人员管理地图标注和地图覆盖层,前者用于标注地点(常见的地图大头针),后者用来突出某区域或者路线等。本期内容:CLLocationMan…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

iOS提供了两个框架用来定位以及地图显示。CoreLocation框架包含的类可以帮助设备确定位置和航向以及使用基于位置的有效信息。MapKit框架未定位提供了户用页面的支持(地图显示),里面包含了地图视图、卫星地图视图以及2D、3D混合视图,并且能够让开发人员管理地图标注和地图覆盖层,前者 用于标注地点(常见的地图大头针),后者用来突出某区域或者路线等。

本期内容:

  • CLLocationManager申请定位权限
  • CLLocationManager获取用户定位
  • CLLocation详细使用,定位数据处理
  • GPX虚拟定位文件的使用以及模拟器定位使用

CLLocationManager 定位管理器

简介:CLLocationManager是用于启动和停止向App获取位置相关的事件的对象。
只有在得到用户许可的情况下,App才能获取设备的当前位置,但是在获取设备位置之前,App还必须确保设备启动了定位服务,当满足这些条件后,App就可以获取启动位置请求的权限并获取当前位置。


CLLocationManager申请定位权限

那我们就开始了,首先要去项目的target里设置info.plist文件字段(苹果的隐私安全需求,不添加是不允许使用的),如下图标注的三个字段:
在这里插入图片描述
接下来我们开始敲代码,创建一个定位管理器CLLocationManager,但是刚刚我们也说过了,如果系统没有打开定位服务,那么我们获得授权也是没用的,所以,首先判断设备是否打开了定位服务:

    // 1.检查定位服务是否开启
    if ([self checkLocationServiceIsEnabled]) { 
   
        // 2.创建定位管理器:
        [self createCLManager];
    }

检查的内部实现:

- (BOOL)checkLocationServiceIsEnabled{ 
   
	// 该方法是类方法,和我们创建的管理器没有关系
    if ([CLLocationManager locationServicesEnabled]) { 
   
        return YES;
    }
    UIAlertController * alertVC = [UIAlertController alertControllerWithTitle:@"提示" message:@"系统定位尚未打开,请到【设定-隐私】中手动打开" preferredStyle:UIAlertControllerStyleAlert];
    UIAlertAction * tipsAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleCancel handler:nil];
    [alertVC addAction:tipsAction];
    [self presentViewController:alertVC animated:YES completion:nil];
    return NO;
}

创建定位管理器内部实现:

- (void)createCLManager{ 
   
    // 创建CoreLocation管理对象
    self.locaationManager = [[CLLocationManager alloc]init];
    // 设定定位精准度
    [self.locaationManager setDesiredAccuracy:kCLLocationAccuracyBest];
    // 设定DistanceFilter可以在用户移动指定距离之后触发更新事件(100米更新一次)
    [self.locaationManager setDistanceFilter:100.f];
    // 设置代理
    self.locaationManager.delegate = self;
    // 开始更新定位
    [self.locaationManager startUpdatingLocation];
}

在这里说一下定位的精准度,这是一个枚举,具体的有以下方式:

精准度枚举 作用
kCLLocationAccuracyBestForNavigation 最佳精确度(汽车导航使用)
kCLLocationAccuracyBest 最佳精确度
kCLLocationAccuracyNearestTenMeters 10米误差
kCLLocationAccuracyHundredMeters 百米误差
kCLLocationAccuracyKilometer 千米误差
kCLLocationAccuracyThreeKilometers 三千米误差

这会儿我们的定位管理器就创建好了,但是到了这一步还是没法使用定位,因为,用户还没有授权给我们的App获取定位权限,所以这会儿我们就需要去主动给用户通知,让用户授权,使用的是CLLocationManager的代理方法:

// 代理方法,定位权限检查
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status{ 
   
    switch (status) { 
   
        case kCLAuthorizationStatusNotDetermined:{ 
   
            NSLog(@"用户还未决定授权");
            // 主动获得授权
            [self.locaationManager requestWhenInUseAuthorization];
            break;
        }
        case kCLAuthorizationStatusRestricted:
        { 
   
            NSLog(@"访问受限");
            // 主动获得授权
            [self.locaationManager requestWhenInUseAuthorization];
            break;
        }
        case kCLAuthorizationStatusDenied:{ 
   
            // 此时使用主动获取方法也不能申请定位权限
            // 类方法,判断是否开启定位服务 
            if ([CLLocationManager locationServicesEnabled]) { 
   
                NSLog(@"定位服务开启,被拒绝");
            } else { 
   
                NSLog(@"定位服务关闭,不可用");
            }
            break;
        }
        case kCLAuthorizationStatusAuthorizedAlways:{ 
   
            NSLog(@"获得前后台授权");
            break;
        }
        case kCLAuthorizationStatusAuthorizedWhenInUse:{ 
   
            NSLog(@"获得前台授权");
            break;
        }
        default:
            break;
    }
}

在上述方法中,我们使用[self.locaationManager requestWhenInUseAuthorization]去主动获得授权,但也需要注意里面的两个场景是无法获得授权的。

完成了以上步骤,我们就可以获得权限了,然后我们开始去获得定位


CLLocationManager获取用户定位

CLLocationManager在获取定位的时候是通过代理方法实现的,该方法包装了类型为CLLocation的定位数据数组,并返回给代理中,具体实现如下:

// 代理方法,更新位置
-  (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{ 
   
    // locations是一个数组提供了一连串的用户定位,所以在这里我们只取最后一个(当前最后的定位)
    CLLocation * newLocation = [locations lastObject];
    // 判空处理
    if (newLocation.horizontalAccuracy < 0) { 
   
        UIAlertController * alertVC = [UIAlertController alertControllerWithTitle:@"提示" message:@"定位错误,请检查手机网络以及定位" preferredStyle:UIAlertControllerStyleAlert];
        UIAlertAction * tipsAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleCancel handler:nil];
        [alertVC addAction:tipsAction];
        [self presentViewController:alertVC animated:YES completion:nil];
        return;
    }
    
    // 获取定位经纬度
    CLLocationCoordinate2D coor2D = newLocation.coordinate;
    NSLog(@"纬度为:%f, 经度为:%f", coor2D.latitude, coor2D.longitude);
    
    // 获取定位海拔高度
    CLLocationDistance altitude = newLocation.altitude;
    NSLog(@"高度为:%f", altitude);
    
    // 获取定位水平精确度, 垂直精确度
    CLLocationAccuracy horizontalAcc = newLocation.horizontalAccuracy;
    CLLocationAccuracy verticalAcc = newLocation.verticalAccuracy;
    NSLog(@"%f, %f", horizontalAcc, verticalAcc);
    
    // 停止更新位置
    [self.locaationManager stopUpdatingLocation];
}

运行效果如下:
在这里插入图片描述
这样我们的位置信息就获取完成了,可能大家看到了,在这个位置信息获取完成之后为什么要写上一个停止更新位置呢?在此我就来解答依稀,一般来说苹果建议我们在获取完位置之后就停止定位,因为电量的消耗是非常大的,但如果我们需要,可以使用以下方法:
[self.locaationManager startMonitoringSignificantLocationChanges]
该方法可以说是一个重大变化通知,避免了随时定位的耗电,当设备检查到数据变化大,就主动调起didUpdateLocations方法来完成位置的改变。

CLLocation详细使用,定位数据处理

在上面我们看到了一个类:CLLocation。和CLLocationManager很像是吧?官方有话说:CLLocation对象包含设备的地理位置和高度,以及指示这些测量值的准确性和收集时间的值。在iOS中,位置对象还包含航向信息,即设备移动的速度和方向。

那我们如何来获得这些信息呢?上代码:

- (void)learningCLLocation{ 
   
    /** 定位管理器返回的位置是用CLLoation实例表示的,里面包含了有关位置的重要信息 比如: CLLocationCoordinate2D 用来表示经纬度坐标 使用方式: CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(latitude, longitude) 创建一个经纬度坐标 coordinate.latitude,coordinate.longitude 读取经纬度 CLLocationDistance 用来表示实际位置和返回坐标之间的距离(以米为单位) 使用方式:获取 location.altitude CLLocationAccuracy 地理坐标的准确性 使用方式:获取 location.horizontalAccuracy; 指定坐标的水平精度(以米为单位) location.verticalAccuracy; 高度值的精度(以米为单位) timestamp 时间戳,指出何时在定位管理器获取的位置 使用方式:获取 location.timestamp CLLocationSpeed 装置运动的速度(以米每秒为单位) 使用方式:获取 location.speed CLLocationDirection 方位角以相对于真北的角度来测量的方位角 使用方式:获取 location.course */
}

已经很详细的表达出来啦,这些数据可能会有用,希望大家能记下来。虽然我们已经获取了定位的数据,但这些数据我们确实看着不懂,那我们该怎么办呢?苹果提供了一个CLGeocoder类,这个类是用于在地理坐标和地名之间转换的接口,也就是常说的逆地理编码(反地理编码)

// 反地理编码(根据当前的经纬度获取具体的位置信息)
CLGeocoder *geocoder = [[CLGeocoder alloc] init];
[geocoder reverseGeocodeLocation:newLocation completionHandler:^(NSArray *placemarks, NSError *error) { 
   
        for (CLPlacemark *placeMark in placemarks) { 
   
            NSLog(@"位置:%@", placeMark.name);
            NSLog(@"街道:%@", placeMark.thoroughfare);
            NSLog(@"子街道:%@", placeMark.subThoroughfare);
            NSLog(@"市:%@", placeMark.locality);
            NSLog(@"区\\县:%@", placeMark.subLocality);
            NSLog(@"行政区:%@", placeMark.administrativeArea);
            NSLog(@"国家:%@", placeMark.country);
        }
    }];

实现之后效果如下:
在这里插入图片描述
这样我们的当前定位数据就是很直观的展现出来啦。


GPX虚拟定位文件的使用以及模拟器定位使用

当我们没有真机调试或者需要进行简单的定位调试的时候,我们会使用GPX虚拟定位文件或者直接使用模拟器的定位工具,可能有的小伙伴不太懂,我这里就给大家讲一下:

  • GPX虚拟定位文件
    首先在工程中 cmd + n 打开文件创建页面,找到gpx文件,如图:在这里插入图片描述
    然后在选择运行设备的地方选择 Eidt Scheme,按照下图方式进行操作:
    在这里插入图片描述
    然后就会在项目中发现我们的GPX虚拟定位文件啦,之后我们在该文件里面作出修改,运行项目,就可以获得目标位置的信息,修改文件内容如下图:
    在这里插入图片描述
    把lat和lng以及name修改就行,时间戳不用修改,这样我们的GPX虚拟定位文件就添加好并可以使用了,使用方式直接选择模拟器运行就可以。如果说GPX文件操作比较繁琐和复杂,我们还可以使用模拟器的工具来进行定位修改,如图:在这里插入图片描述
    在这里插入图片描述
    然后输入目标经纬度就可以完成位置录入了。

补充说明:

之前面试的时候谈及耗电量优化,在新的API中,苹果提供了单次定位请求的功能,也就是获取一次位置信息,代码:

[self.locaationManager requestLocation]

其实现逻辑是按照定位精确度从低到高进行排序,逐个进行定位。如果在有效时间内,定位到了精确度最好的位置,那么就把对应的位置通过代理告知外界,如果获取到的位置不是精确度最高的那个,也会在定位超时后,通过代理告诉我们。需要注意的是:必须实现代理的locationManager:didFailWithError:方法,不能与startUpdatingLocation方法同时使用。
实现如下:

// 代理方法,错误处理
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{ 
   
    NSLog(@"%@",error);
    // 如果管理器未能获取位置,可能是GPS或者网络信号不可用等情况,这时候不要再继续消耗性能
    // 停止更新位置
    [self.locaationManager stopUpdatingLocation];
}

好了这期的内容到这里就结束了,下期就开讲原生的MapKit,到时候直接是可视化的地图定位信息,大家伙期待吗?~

下期内容:MapKit的实际应用
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/158797.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 搜索、推荐、广告系统等人工智能优质技术资源最全整理[通俗易懂]

    搜索、推荐、广告系统等人工智能优质技术资源最全整理[通俗易懂]前沿文章目录前沿开源地址[算法学习资料:AI_Tutorial](https://github.com/cbamls/AI_Tutorial)开源相关LuceneSolrElasticLucidWorks中文分词大公司阿里百度京东美团点评携程去哪儿搜狗一号店待分类开发应用理论基础源码解读常见问题其他人工智能领域文集算法学习资料:AI_Tutorial人工智能、AI架构、搜索系统、推荐系统…

    2022年5月5日
    38
  • nslookup命令的使用方法_怎么退出nslookup命令

    nslookup命令的使用方法_怎么退出nslookup命令nslookup是一款查询DNS(Internetdomainnameserver)的程序。用来网络管理工具,帮助诊断和解决DNS相关的问题。除此之外,也有其他DNS工具,如dig命令和host命令。nslookup会将DNS查询发送到指定的DNS服务器、接收DNS回复,并显示结果1、查找A记录2、查找MX记录3、查找NS记录4、查找CNAME记录5、查找SOA记录6、查找RDNSorPRT记录直接输入IP地…

    2022年10月19日
    2
  • CAP原理和数据高可用性

    CAP原理和数据高可用性对网站而言,数据是最宝贵的资源,硬件可以购买,软件可以重构,但是数据(用户数据,交易数据,商品数据)一旦丢失,对网站的打击可以说是毁灭性的。数据高可用性数据高可用性包括如下几个方面的含义数据持久性保证数据可以持久存储,在各种情况下都不会出现数据丢失。为了实现数据持久性,不但在写入数据是需要写入持久性存储,还需要将数据备份到一个或多个副本,存放在不同的物理存储设备上,在某个存储故障发生是,数据不会丢失

    2022年5月12日
    44
  • java定义数组_java中数组的三种定义方式_java中数组的定义及使用方法(推荐)…

    java定义数组_java中数组的三种定义方式_java中数组的定义及使用方法(推荐)…描述java中数组的三种定义方式java中,数组是一种很常用的工具,今天我们来说说数组怎么定义[java]viewplaincopy/***数组的三种定义方法*1.数组类型[]数组名=new数组类型[数组长度];*2.数组类型[]数组名={数组0,数组1,数组2,数组3,。。。。};*3.数组类型[]数组名=new数组类型[]{数组0,数组1,数组2,。。。};**/p…

    2022年7月8日
    20
  • pycharm2021.4.3激活破解方法

    pycharm2021.4.3激活破解方法,https://javaforall.net/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

    2022年3月15日
    179
  • vim 删除多行方法

    vim 删除多行方法比如想删除一个文件的1-42行的前2列:gg#到文件首ctrl+v#可视块模式42j,2l#注意是小写的J和L(使用方向键向下和向右来选择删除区域也可以)d#删除…

    2022年6月29日
    30

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号