Swift基于CoreLocation框架获取设备的当前地理位置
Swift基于CoreLocation框架获取设备的当前地理位置

Swift基于CoreLocation框架获取设备的当前地理位置

获取当前地理位置代码

下面的代码是是一个基于 CoreLocation 框架的自定义位置获取工具类,用于在应用程序中获取设备的当前地理位置。

import CoreLocation

class LocationFetcher: NSObject, CLLocationManagerDelegate {
    let manager = CLLocationManager()
    var lastKnownLocation: CLLocationCoordinate2D?

    override init() {
        super.init()
        manager.delegate = self
    }

    func start() {
        manager.requestWhenInUseAuthorization()
        manager.startUpdatingLocation()
    }

    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        lastKnownLocation = locations.first?.coordinate
    }
}

代码解析

1、定义 LocationFetcher 类

继承自 NSObject 并实现了 CLLocationManagerDelegate 协议。

这个类封装了位置服务的启动、授权请求以及位置更新逻辑。

2、manager和lastKnownLocation属性

let manager = CLLocationManager()
var lastKnownLocation: CLLocationCoordinate2D?

manager: CLLocationManager 实例,用于管理设备的定位服务。

lastKnownLocation: 存储最近一次获取到的位置(CLLocationCoordinate2D 类型)。

3、init 方法

初始化时,将当前实例设置为 manager 的代理,以接收定位回调。

4、start 方法

请求用户授权访问位置数据 (requestWhenInUseAuthorization)。

启动位置更新 (startUpdatingLocation),后台会不断获取设备的地理位置。

5、locationManager(_:didUpdateLocations:) 回调

当 CLLocationManager 获取到新的位置信息时,会调用此回调。

locations 是一个 CLLocation 数组,取数组中的第一个位置(最新位置)并存储到 lastKnownLocation。

如何调用该代码

以下是如何在应用中使用 LocationFetcher 类的示例:

1、初始化和启动位置服务

let locationFetcher = LocationFetcher()

func fetchLocation() {
    locationFetcher.start() // 启动位置服务
}

2、获取位置

在需要获取位置时,可以访问 lastKnownLocation:

if let location = locationFetcher.lastKnownLocation {
    print("Latitude: \(location.latitude), Longitude: \(location.longitude)")
} else {
    print("Location not available yet")
}

实际应用

在调取locationFetcher.start()方法后,会弹出获取当前地理位置的请求。

在显示视图中,可以根据locationFetcher.lastKnownLocation获取到最近的一次定位。

注意事项

1、权限声明

在 Info.plist 中添加定位服务权限说明:

Privacy - Location When In Use Usage Description

如果不知道Info.plist文件,可以查看《Xcode项目Info.plist文件位置

2、电池消耗

使用定位服务可能会影响设备的电池寿命。使用 startUpdatingLocation 时应注意停止不必要的更新(例如在获取一次位置后调用 stopUpdatingLocation)。

manager.stopUpdatingLocation()

3、精度要求

如果需要更高的精度,可以设置 CLLocationManager 的 desiredAccuracy 属性,例如:

manager.desiredAccuracy = kCLLocationAccuracyBest

相关知识可以进一步阅读《Swift高精度定位desiredAccuracy

适用场景

需要获取设备的当前位置,例如用于地图导航、地理打卡等。

用于需要持续或实时获取位置的功能,但要注意隐私问题和用户授权。

参考文章

SwiftUI 100天 – Time for MapKit:https://www.hackingwithswift.com/100/swiftui/78

代码示例

使用stopUpdatingLocation方法的定位代码

import CoreLocation

class LocationFetcher: NSObject, CLLocationManagerDelegate {
    private let manager = CLLocationManager()
    private(set) var lastKnownLocation: CLLocationCoordinate2D?
    
    override init() {
        super.init()
        manager.delegate = self
    }
    
    func start() {
        manager.requestWhenInUseAuthorization() // 请求用户授权
        manager.startUpdatingLocation() // 开始定位
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        if let location = locations.first?.coordinate {
            lastKnownLocation = location
            print("获取到的位置: \(location.latitude), \(location.longitude)")
            
            // 获取到位置后,停止更新
            manager.stopUpdatingLocation()
            print("停止位置更新以节省电池寿命")
        }
    }
    
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        print("定位失败: \(error.localizedDescription)")
        manager.stopUpdatingLocation() // 出现错误时也应停止更新
    }
}

相比之前的代码,每次调用start()方法后,只会获取一次定位,然后停止获取。

执行效果

1、点击 “开始定位” 按钮后,应用会请求用户授权访问位置信息。

2、一旦获取到位置信息,会在控制台打印设备的纬度和经度:

获取到的位置: 37.7749, -122.4194
停止位置更新以节省电池寿命
这个类的用途

1、简化定位服务的使用

开发者只需要调用 start() 方法即可启动定位服务。

定位结果和错误都会通过 lastKnownLocation 或控制台日志反馈。

2、适合一次性定位的场景

比如需要获取用户当前位置以进行某些操作(天气查询、地图标记等)。

获取到位置后会自动停止更新,减少电池消耗。

为什么这样做重要?

1、节省电池寿命

持续更新位置会耗费大量电量,尤其是在启用 GPS 的情况下。

不必要的更新会让用户的设备快速耗电,影响用户体验。

2、提升性能

定位服务会占用系统资源,不必要的调用可能降低设备性能。

3、符合最佳实践

合理使用系统资源是 iOS 开发的一个重要原则。

优化实现方式

如果需要多次定位或连续使用,可以通过以下方式调整逻辑:

1、保持定位器状态

改为不在每次成功获取位置后立即停止,而是根据需要手动控制停止:

func stop() {
    manager.stopUpdatingLocation()
    print("手动停止位置更新")
}

调用 locationFetcher.stop() 方法手动停止更新。

2、状态标志优化

使用一个标志位来控制是否需要持续定位,例如:

var shouldKeepUpdating = false

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    if let location = locations.first?.coordinate {
        lastKnownLocation = location
        print("获取到的位置: \(location.latitude), \(location.longitude)")
        
        if !shouldKeepUpdating {
            manager.stopUpdatingLocation()
            print("停止位置更新")
        }
    }
}

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开放者。

发表回复

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