You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Swift中使用Core Location?求Location Manager及代理相关指导

在Swift中用Core Location:Location Manager和代理实操指南

1. 前期准备

先导入CoreLocation框架,然后必须在Info.plist里配置权限描述:

  • 只需要前台获取位置:添加NSLocationWhenInUseUsageDescription,值要写清楚获取位置的原因(比如“获取您的位置以展示附近商家”)
  • 需要后台持续定位:还要添加NSLocationAlwaysAndWhenInUseUsageDescription(iOS11及以上适用),旧版系统用NSLocationAlwaysUsageDescription

2. Location Manager初始化&代理绑定

核心要点:必须强持有Location Manager实例,要是搞成局部变量,ARC一释放,代理方法根本不会触发。

直接上代码示例:

import CoreLocation

class LocationHelper: NSObject, CLLocationManagerDelegate {
    // 用类属性强持有,别搞成局部变量!
    private let locationManager = CLLocationManager()
    
    override init() {
        super.init()
        // 绑定代理
        locationManager.delegate = self
        // 设置精度:按需选择,精度越高越耗电
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
    }
    
    // 请求权限的方法
    func askForLocationPermission() {
        guard CLLocationManager.locationServicesEnabled() else {
            print("系统位置服务没开,去设置里打开先")
            return
        }
        
        switch locationManager.authorizationStatus {
        case .notDetermined:
            // 请求前台权限,要后台的话换成requestAlwaysAuthorization()
            locationManager.requestWhenInUseAuthorization()
        case .restricted, .denied:
            print("位置权限被拒了,得去设置里改权限")
        case .authorizedWhenInUse, .authorizedAlways:
            // 权限到手,开始拿位置
            startTrackingLocation()
        @unknown default:
            break
        }
    }
    
    // 开始更新位置
    func startTrackingLocation() {
        locationManager.startUpdatingLocation()
    }
    
    // 不用了就停,省点电
    func stopTrackingLocation() {
        locationManager.stopUpdatingLocation()
    }
}

3. 代理方法核心用法

代理是你获取位置、处理权限变化、捕获错误的关键,常用的几个方法:

3.1 权限状态变化时触发

用户点了授权/拒绝,或者系统权限变化时调用:

func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
    switch manager.authorizationStatus {
    case .authorizedWhenInUse, .authorizedAlways:
        startTrackingLocation()
    case .denied, .restricted:
        print("没权限,拿不到位置")
    default:
        break
    }
}

3.2 获取到位置数据时触发

每次Location Manager获取到新位置就会调用,最新的位置在数组最后一位:

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    guard let currentLocation = locations.last else { return }
    
    // 提取经纬度
    let lat = currentLocation.coordinate.latitude
    let lon = currentLocation.coordinate.longitude
    print("当前位置:纬度\(lat),经度\(lon)")
    
    // 如果只需要一次位置,拿到就停止更新,避免持续耗电
    stopTrackingLocation()
}

3.3 获取位置失败时触发

遇到信号差、权限不足等问题时调用:

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
    if let clError = error as? CLError {
        switch clError.code {
        case .locationUnknown:
            print("找不到当前位置,可能信号差")
        case .denied:
            print("权限被拒,拿不了位置")
        default:
            print("获取位置出错:\(clError.localizedDescription)")
        }
    } else {
        print("未知错误:\(error.localizedDescription)")
    }
}

4. 避坑指南

  • 别让Location Manager被释放:一定要用类属性持有,局部变量会被ARC回收,导致代理方法永远不会执行。
  • 权限描述不能少:Info.plist里没加权限描述的话,App会直接崩溃,或者弹不出权限请求框。
  • 后台定位要额外配置:需要后台持续定位的话,除了权限声明,还要在Xcode的Signing & Capabilities里添加Background Modes,勾选Location updates。
  • 精度按需选择:别上来就用最高精度,比如只需要城市级定位,用kCLLocationAccuracyThreeKilometers就行,能大幅降低耗电。

内容的提问来源于stack exchange,提问作者ChessMaster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 17:57:19