前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >iOS开发-用户定位获取-CoreLocation的实际应用-CLLocationManger获取定位权限-CLLocation详细使用方式

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

作者头像
全栈程序员站长
发布于 2022-09-17 06:54:25
发布于 2022-09-17 06:54:25
4.7K00
代码可运行
举报
运行总次数:0
代码可运行

大家好,又见面了,我是你们的朋友全栈君。

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

本期内容:

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

CLLocationManager 定位管理器

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


CLLocationManager申请定位权限

那我们就开始了,首先要去项目的target里设置info.plist文件字段(苹果的隐私安全需求,不添加是不允许使用的),如下图标注的三个字段:

接下来我们开始敲代码,创建一个定位管理器CLLocationManager,但是刚刚我们也说过了,如果系统没有打开定位服务,那么我们获得授权也是没用的,所以,首先判断设备是否打开了定位服务:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    // 1.检查定位服务是否开启
    if ([self checkLocationServiceIsEnabled]) { 
   
        // 2.创建定位管理器:
        [self createCLManager];
    }

检查的内部实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
- (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;
}

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
- (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的代理方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 代理方法,定位权限检查
-(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的定位数据数组,并返回给代理中,具体实现如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 代理方法,更新位置
-  (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中,位置对象还包含航向信息,即设备移动的速度和方向。

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
- (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类,这个类是用于在地理坐标和地名之间转换的接口,也就是常说的逆地理编码(反地理编码)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 反地理编码(根据当前的经纬度获取具体的位置信息)
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中,苹果提供了单次定位请求的功能,也就是获取一次位置信息,代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[self.locaationManager requestLocation]

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

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

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

下期内容:MapKit的实际应用

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
短信中的链接为什么那么短?
短网址服务是用于缩短网址,方便用户记忆和访问的一种服务。它通常通过将长网址与短网址服务提供的接口进行匹配,从而实现缩短网址的目的。短网址服务可以降低用户输入长网址时的错误率,提高用户体验,同时也可以减轻服务器的压力,提高网站的访问速度。目前市面上有许多短网址服务,如google的goo.gl、新浪的sina.lt等。
IMWeb前端团队
2018/01/08
6K2
短信中的链接为什么那么短?
字节二面:100Wqps短链系统,如何设计?
这段时间,在整理知识星球中面试专栏时看到这么一个字节跳动的二面真题:100Wqps短链系统,怎么设计?
码猿技术专栏
2023/05/01
4.5K1
字节二面:100Wqps短链系统,如何设计?
永久短网址生成 可以永久使用的短链接推荐
微博、短信、微信在推送信息的时候都有字符的数量限制,如果分享一个长网址,很容易就超出限制,发不出去。短网址服务可以把一个长网址变成短网址,方便在社交网络上传播。
全栈程序员站长
2022/09/02
6.8K0
永久短网址生成 可以永久使用的短链接推荐
记一次在买书过程中发现的短链接安全
本篇文章作者YanXia,本文属i春秋原创奖励计划https://bbs.ichunqiu.com/thread-63288-1-1.html,未经许可禁止转载。
YanXia
2023/04/28
3010
记一次在买书过程中发现的短链接安全
面试必备:如何将一个长URL转换为一个短URL?
前几天整理面试题的时候,有一道试题是《如何将一个很长的URL转换为一个短的URL,并实现他们之间的相互转换?》,现在想起来这是一个绝对不简单的问题,需要考虑很多方面,今天和大家一起学习研究一下!
Java后端技术
2018/08/09
7.7K0
面试必备:如何将一个长URL转换为一个短URL?
如何设计一个短链接系统
短链接是一种将长URL地址转换为较短、易于记忆的链接的技术。它通过使用特定的算法或服务将长链接压缩成更短的形式,以便在限制字符长度或需要更简洁的场景下使用。
柯柏技术笔记
2024/01/10
8710
如何设计一个短链接系统
短网址(short URL)系统的原理及其实现
作者: 小猿大圣 https://segmentfault.com/a/1190000012088345 背景 提供一个短址服务。 你有没有发现,我们的任务中出现长 URL 就会比较麻烦?
前端教程
2018/03/05
5.3K0
短网址(short URL)系统的原理及其实现
如何实现一个短链接服务 | 短链接生成原理
短链接,通俗来说,就是将长的URL网址,通过程序计算等方式,转换为简短的网址字符串。
梦溪
2021/08/09
19.4K3
最近学到的「短链接」知识
最近接了一个需求,涉及到了短链接的相关的知识,于是去查阅了相关的资料,在这里给大家整理分享一下。
Java3y
2019/10/15
1.7K0
最近学到的「短链接」知识
短网址安全浅谈
何谓短网址(Short URL)?顾名思义,就是形式上比较短的网址,当前主要是借助短网址来替代原先冗长的网址,方便传输和分享。短网址服务也就是将长网址转换为短网址的服务,这种服务在方便了广大网民的同时也带来了一定的安全风险。
腾讯安全应急响应中心
2018/10/16
1.9K0
短网址安全浅谈
用cloudflare搭建免费的个人短链接平台
短链接又称短网址、短码,意思就是形式上比较短的网址。短链接服务,可以通过将一个普通的冗长的网址缩短生成一个新的较短的网址,便于分享传播。
六月河
2022/09/26
4.7K0
用cloudflare搭建免费的个人短链接平台
【愚公系列】2022年03月 .NET CORE工具案例-短链接服务
短链接,通俗来说,就是将长的URL网址,通过程序计算等方式,转换为简短的网址字符串。
愚公搬代码
2022/03/04
4270
东半球最接地气的短链接系统设计
今天下午,烟哥和同事在厕所里排队等坑的时候(人多坑少)。想象一下一个场景,我正在一边排队,一边拿着手机撩妹。前面一个同事,拿着手机短信转过头来和我聊天。
Java3y
2019/11/12
6610
东半球最接地气的短链接系统设计
如何利用H5短网址快速缩短长网址
你是否曾经需要共享一个链接,但是URL这么长,它看起来更像是一个乱码的鸡肋?没有必要担心,因为在线上有非常聪明的服务叫网址缩短器。这些服务将为您创建一个新的短链接,然后引导那些用户通过短连接访问您的很长的乱码的鸡肋URL。现在,你可以与任何你感兴趣的人分享这个链接,而不用担心干扰你的电子邮件、短信或微信朋友圈。
赵小磊
2018/11/08
4.1K0
如何利用H5短网址快速缩短长网址
新浪短网址生成器等短链接工具的原理(第二章)
短网址顾名思义就是一个很短的链接和网址,常用于将一个长连接缩短成一个短链接,方便利于推广。  url.cn短网址,可能很多朋友都已经不再陌生,特别是在微博、微信、朋友圈、QQ群、短信息等应用中十分普遍,短网址的前身是在企鹅微博发微博时有时发很长的网址连接,但由于微博只限制140个字,所以微博就自动把您发的长网址给转换成短网址了。  企鹅短链接(url.cn/xxx)属于企鹅微博旗下的短网址,原先是微博在使用。短网址生成可以有效的避免链接过长,推广不便等因素 生成t.cn短连接后更有利于在微信推广和QQ群中推广 !目前过国内使用最多的短网址有三家。其中t.cn 属于新浪短链接,url.cn属于腾讯短链接,dwz.cn属于百度!今天我们要说的就是url.cn短网址!
南昌谢大脚
2020/04/23
2.5K0
短链接原理及其算法实现
短网址在目前来说是一个非常流行的东西,提供短网址服务的网站也是相当多的,短网址在微博上应用的比较广泛 ,因为微博对于url的长度有一个限制,所以将一个很长的网址转换成一个很短的网址,是一个非常棒的想法,其好处有很多,比如字符少,美观,便于发布和传播等。
OECOM
2020/07/01
5.3K0
Python竟然能把“长的”变成“短的”?
最近我遇到了一些问题:需要将几百条长链接转成短链接。经过一番学习,发现Python可以轻松解决这个问题,不仅可以实现缩短【长链接→短链接】,也可以实现还原【短链接→长链接】。
快学Python
2022/06/10
8150
Python竟然能把“长的”变成“短的”?
URL短网址生成算法原理
短网址(Short URL),是在形式上比较短的网址,通过映射关系跳转到原有的长网址。
阳光岛主
2019/02/18
4.6K2
URL短链接实现方法
最近项目开发中,需要实现URL长链接转短链接的需求,于是在网上找了一些资料,顺便整理了下,欢迎有想法的童鞋踊跃留言,我们共同探讨。
wangxl
2018/02/25
7.6K1
URL短链接实现方法
搭建短链接平台详细分析及具体代码实现
短链接,又称缩略网址服务、缩址、短址、短网址、缩略网址、网址缩短、缩短网址、URL缩短等,指的是一种互联网上的技术与服务。此服务可以提供短URL以代替原来可能较长的URL,将长的URL地址缩短。
Mintimate
2021/08/12
3.9K0
搭建短链接平台详细分析及具体代码实现
推荐阅读
相关推荐
短信中的链接为什么那么短?
更多 >
LV.1
这个人很懒,什么都没有留下~
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档