如何在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
相关产品推荐
相关产品推荐

