SwiftUI获取用户的位置信息(CLLocationManager,CLLocationManagerDelegate)

本篇文章将会介绍一下在SwiftUI中如何通过CorLocation框架获取用户的位置信息,因为获取位置信息属于用户的隐私信息,所以需要在Info.plist文件里面加上访问位置权限的说明。
在这里插入图片描述
关于位置信息,可以请求两种级别的许可:alwayswhen in use。根据我们应用需求进行选择。我们需要在Info.plist文件上上添加这个条目,同时必须提供一个描述,向用户解释为什么你的应用程序需要位置信息(该文本将出现在询问用户权限的对话框中),比如说:“XXX App需要访问您的位置以提供基于位置的服务。”

本文采用when in use这种方式:
![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/bb719f87fd4e48dd9f578e6e7abdee60.png = 600x)

下面创建一个处理位置信息的类LocationManager

import Foundation
import CoreLocationfinal class LocationManager: NSObject, CLLocationManagerDelegate, ObservableObject {// 记录位置信息@Published var currentLocation: CLLocationCoordinate2D?// 初始化CLLocationManager实例private var locManager = CLLocationManager()func checkLocationAuthorization() {// 设置代理locManager.delegate = self// 获取用户授权状态let authorizationStatus = locManager.authorizationStatusDispatchQueue.global().async { [weak self] in// 判断用户设备的系统位置权限是否开启,而非App的。该判断需要异步进行,否则会卡主线程。if CLLocationManager.locationServicesEnabled() {// 如果设备系统位置权限开启了,回主线程继续操作DispatchQueue.main.async {if authorizationStatus == .authorizedAlways || authorizationStatus == .authorizedWhenInUse {// 如果用户授权了,开启位置更新。self?.locManager.startUpdatingLocation()} else if authorizationStatus == .notDetermined {// 如果用户未曾选择过,那么弹出授权框。self?.locManager.requestWhenInUseAuthorization()} else {// 用户拒绝了,停止位置更新。self?.locManager.stopUpdatingLocation()}}} else {// 如果设备系统位置权限未开启,回主线程继续操作DispatchQueue.main.async {if authorizationStatus == .notDetermined {// 如果用户未曾选择过,那么弹出授权框。self?.locManager.requestWhenInUseAuthorization()} else {// 因系统位置权限未开启,停止位置更新。self?.locManager.stopUpdatingLocation()}}}}}// MARK: - CLLocationManagerDelegate// 每当位置更新时都会被调用,这里更新currentLocation变量。func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {if let newLocation = manager.location, !(newLocation.coordinate.longitude == 0.0 && newLocation.coordinate.latitude == 0.0) {currentLocation = newLocation.coordinate}}// 当位置管理器无法获取位置或发生错误时调用。func locationManager(_ manager: CLLocationManager, didFailWithError error: any Error) {currentLocation = nillocManager.delegate = nillocManager.stopUpdatingLocation()}// 当用户的位置权限状态发生变化时调用,例如用户从拒绝状态改为允许状态。用于根据当前的授权状态调整应用的行为,如在用户授权后开始位置更新。func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {if manager.authorizationStatus == .denied {locManager.stopUpdatingLocation()} else if manager.authorizationStatus == .authorizedAlways || manager.authorizationStatus == .authorizedWhenInUse {locManager.startUpdatingLocation()}}
}

完整代码如上,下面逐步看一下:

首先LocationManager类继承了NSObject类,并实现了CLLocationManagerDelegateObservableObject协议。
实现CLLocationManagerDelegate协议是为了处理位置信息以及授权等变更的情况;
实现ObservableObject协议,并定义了一个@Published变量,供UI显示位置信息使用。

在该类中定义两个属性,说明见注释。

  // 记录位置信息,变化时通知用到该变量的UI进行刷新。@Published var currentLocation: CLLocationCoordinate2D?// 初始化CLLocationManager实例private var locManager = CLLocationManager()

目前该类还提供了一个对外的方法checkLocationAuthorization(),该方法内设置了delegate,判断系统位置权限情况以及用户针对App的授权情况,根据不同的情况采取对应的处理方式,具体见注释。

特别说明一下CLLocationManager.locationServicesEnabled()方法获取系统位置授权情况,需要在异步进行,否则卡UI。

CLLocationManagerDelegate中,我们实现了三个基本的方法,分别处理位置信息变更,位置信息获取失败,以及用户授权状态的改变。

上面都搞定后,弄个界面显示一下位置信息:

struct LocationViewDemo: View {@StateObject private var locationManager = LocationManager()var body: some View {VStack(spacing: 30) {if let currentLocation = locationManager.currentLocation {VStack(spacing: 20) {Text("Latitude: \(currentLocation.latitude)")Text("Longitude: \(currentLocation.longitude)")}}Button("Get location") {locationManager.checkLocationAuthorization()}.buttonStyle(.borderedProminent)}.padding()}
}

App首次运行起来后:
请添加图片描述
点击后:
请添加图片描述
授权后,位置信息就显示出来了。
请添加图片描述

弹出授权框,我们可以调用下面两个方法,不同的方法对应Info.plist文件中不同配置,匹配不上就无法弹框了。

requestAlwaysAuthorization()
requestWhenInUseAuthorization()

关于manager,还有一个请求一次位置信息的方法:

locManager.requestLocation()

CLLocationManagerDelegate代码方法的说明:

// 每当位置更新时都会被调用,这里更新currentLocation变量。
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
// 当位置管理器无法获取位置或发生错误时调用。
func locationManager(_ manager: CLLocationManager, didFailWithError error: any Error)
/// 当用户的位置权限状态发生变化时调用,例如用户从拒绝状态改为允许状态。
/// 用于根据当前的授权状态调整应用的行为,如在用户授权后开始位置更新。
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager)
/// 位置更新暂停时被调用
func locationManagerDidPauseLocationUpdates(_ manager: CLLocationManager)
/// 位置更新恢复时被调用
func locationManagerDidResumeLocationUpdates(_ manager: CLLocationManager)
/// 用户进入一个地理区域时被调用
func locationManager(_ manager: CLLocationManager, didEnterRegion region: CLRegion)
/// 用户离开一个地理区域时被调用
func locationManager(_ manager: CLLocationManager, didExitRegion region: CLRegion)

最后,希望能够帮助到有需要的朋友,如果觉得有帮助,还望点个赞,添加个关注,笔者也会不断地努力,写出更多更好用的文章。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/23933.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

视频剪辑去水印软件推荐 视频剪辑去水印方法

不会去水印,很难做好视频剪辑。选对软件、掌握去水印的方法,是每个剪辑师必须经历的过程。真正擅长视频剪辑去水印的软件,一定具备多种去水印功能。剪辑师可以根据素材的具体情况,选择最恰当的去水印方法。有关视频剪辑去水印软件…

JimuReport 积木报表 v1.7.5 版本发布,免费的低代码报表

项目介绍 一款免费的数据可视化报表工具,含报表和大屏设计,像搭建积木一样在线设计报表!功能涵盖,数据报表、打印设计、图表报表、大屏设计等! Web 版报表设计器,类似于excel操作风格,通过拖拽完…

【日记】遇到了一个很奇怪的大爷(845 字)

正文 花了昨天和今天两天时间,把数据转移完了。这块 2T 的硬盘可以光荣退休了。目前是没什么存储焦虑了。 农发行净开发一些垃圾系统。今天没什么业务,但跟 ActiveX 斗智斗勇了一整天,最后实在搞不过 IE 浏览器。我也懒得管了,又不…

禁用layui树形表格的多选框checkbox

1. 背景 在使用树形表格渲染数据时,需要对数据进行批量操作。相对于选中数据后,再做错误提示。直接把数据的多选框禁用掉更加直观。 2. 实现 DisabledTableCheckBox: () > {// 获取所有行 var tableElem $(".layui-table-fixed-l");var …

一脉阳光上市圆梦:销售成本高昂,两大创始人的行贿往事与屡屡被罚

《港湾商业观察》施子夫 2024年6月7日,江西一脉阳光集团股份有限公司(以下简称,一脉阳光)将正式在港交所主板挂牌上市(以下简称,一脉阳光;股票代码02522.HK),公司预计发…

Vue3【七】setup的语法糖setup简写方法

Vue3【七】setup的语法糖setup简写方法 Vue3【七】setup的语法糖setup简写方法 使用script标签式写法称为setup语法糖 组件名称默认位文件名 export 的内容可以省略 案例截图 案例目录 案例代码 Person.vue <template><div class"person"><h1>我…

这才是计科之 Onix XV6 源码分析(1、XV6-x86的启动)

这才是计科之 Onix & XV6 源码分析&#xff08;1、XV6-x86的启动&#xff09; 前言 Onix是一款相对于XV6来说功能更为健全的单核OS&#xff0c;由于功能更加完善&#xff0c;Onix也更加复杂。代码阅读起来会比较绕。 XV6是一款简单易读的多核操作系统&#xff0c;但其功…

【JMeter接口测试工具】第一节.JMeter简介和安装【入门篇】

文章目录 前言一、JMeter简介 1.1 JMeter基本介绍 1.2 JMeter优缺点二、JMeter安装 2.1 JMeter安装步骤 2.2 JMeter环境配置三、项目介绍 3.1 项目简介 3.2 API接口清单总结 前言 一、JMeter简介 1.1 JMeter基本介绍 JMeter 是 Apache 组织使用…

java---程序逻辑控制(详解)

目录 一、概述二、顺序结构三、分支结构3.1 if语句3.1.1 语法格式13.1.2 语法格式23.1.3 语法格式3 3.2 练习3.2.1 判断一个数字是奇数还是偶数3.2.2 判断一个数字是正数&#xff0c;负数&#xff0c;还是零3.2.3 判断一个年份是否为闰年 3.3.switch语句 四、循环结构4.1 while…

Flutter vscode环境如何进行真机测试

目录 1. 准备工作 1.1 安装Flutter和VS Code 1.2 安装必要的VS Code扩展 1.3 手机设置 2. 配置VS Code调试环境 3. 手机如何退出开发者模式 1. 准备工作 1.1 安装Flutter和VS Code 确保你已经在电脑上安装了Flutter SDK和VS Code。如果还没有&#xff0c;可以参考以下指…

项目文章 | Nature Commun蓝藻转录因子PhoB对磷/铁的营养元素限制的调控机制

近日&#xff0c;华中师范大学邱保胜教授团队在《Nature Communications》发表题为“Phosphorus deficiency alleviates iron limitation in Synechocystis cyanobacteria through direct PhoB-mediated gene regulation”文章&#xff0c;其重点研究了Synechocystis蓝藻转录因…

硬件产品经理

边端协调管理平台 主页模型管理配置管理设备管理设备检测组态数据服务传输通道服务 定义与范围&#xff1a; 边测&#xff1a;通常指的是边缘计算的测试&#xff0c;这里的“边缘”可以理解为离用户更近的计算节点或设备&#xff0c;如小 型数据中心、具有计算能力的小基站等。…

深度学习课程设计:构建未来的教育蓝图

深度学习课程设计&#xff1a;构建未来的教育蓝图 在近年来&#xff0c;深度学习已经从一项前沿的技术发展成为计算机科学领域不可或缺的一部分。随着其在多个行业中的应用日益增多&#xff0c;对深度学习教育的需求也在急剧上升。对于计划将深度学习纳入学术课程的教育者而言…

【WRF理论第二期】运行模型的基础知识

WRF理论第二期&#xff1a;运行模型的基础知识 1 Basics for Running the Model2 Geogrid程序2.1 Geogrid2.2 Terrestrial Input Data 3 Ungrid程序3.1 Ungrid3.2 Intermediate Files3.3 Required Fields 4 Metgrid程序参考 官方介绍-Basics for Running the Model 本博客主要…

耐用好用充电宝有哪些?畅销排行榜前四款充电宝推荐

在日常生活中&#xff0c;一款耐用且好用的充电宝是我们出行必备的利器&#xff0c;它可以为我们的手机、平板等设备提供持续的电力支持。然而&#xff0c;在市面上琳琅满目的充电宝品牌中&#xff0c;究竟哪些才是真正耐用又好用的选择&#xff1f;为了帮助大家更好地了解市场…

Qt5学习笔记(一):Qt Widgets Application项目初探

笔者长期使用MFC开发Windows GUI软件。随着软件向Linux平台迁移的趋势越发明朗&#xff0c;GUI程序的跨平台需求也越来越多。因此笔者计划重新抓一下Qt来实现跨平台GUI程序的实现。 0x01. 看看Qt Widgets Application项目结构 打开Qt5&#xff0c;点击“ New”按钮新建项目。…

基于Kubernetes和DeepSpeed进行分布式训练的实战教程

目录 ​编辑 一、前期准备 二、部署和配置训练任务 三、编写和运行训练代码 四、监控和调优 五、代码实现 5.1. Dockerfile 5. 2. DeepSpeed 配置文件 (ds_config.json) 5.3. Kubernetes 部署文件 (deployment.yaml) 5.4. PyTorch 训练脚本 (train.py) 注意事项&am…

windows任意窗口置顶/前台显示/不被最小化或遮挡

问题&#xff1a;在办公时&#xff0c;当同时需要打开好几个重要的窗口&#xff0c;比如需要对若干个文件夹里的文件进行操作&#xff0c;几个窗口都需要一直在桌面前台显示&#xff0c;但这样的话容易在打开其他页面或是切其他窗口的时候被遮挡&#xff0c;因此考虑如何让几个…

我们如何用npm发布自己的插件包?详细的教程来了

一、什么是npm插件&#xff1f; npm&#xff08;“Node 包管理器”&#xff09;是 JavaScript 运行时 Node.js 的默认程序包管理器。npm插件是指通过npm安装的第三方包&#xff0c;可以在Node.js项目中直接使用。这些插件涵盖了各种领域&#xff0c;包括Web开发、数据测试、构建…

用于精准治疗和预防细菌感染的生物功能脂质纳米颗粒

引用信息 文 章&#xff1a;Biofunctional lipid nanoparticles for precision treatment and prophylaxis of bacterial infections. 期 刊&#xff1a;Science Advances&#xff08;影响因子&#xff1a;13.6&#xff09; 发表时间&#xff1a;2024年4月5日 作 者&a…