定位服务有什么新功能
What's new in location
2020年6月23日
一句话判断
iOS 14 对定位权限做了大幅调整——新增「大致位置」选项、临时精确定位授权、以及后台位置使用的显著 UI 提示,用户的隐私控制粒度大幅提升,你的 app 需要重新审视定位权限的使用方式。
这场 Session 讲了什么
这场 Session 聚焦于 iOS 14 中 Core Location 的三大变化:
第一,新增「大致位置」(Approximate Location)权限。用户现在可以选择只给 app 一个模糊的城市级位置,而不是精确的 GPS 坐标。这是对现有「使用时允许」「始终允许」「不允许」之外的第四种选择。
第二,临时精确定位授权。如果 app 默认只拿到大致位置,但某个功能确实需要精确定位(比如导航),可以通过 requestTemporaryFullAccuracyAuthorization 弹出一次性授权请求,用户批准后 app 在本次使用中获得精确位置。
第三,后台位置使用的透明度增强。当 app 在后台使用位置时,iOS 14 会在状态栏显示持续的通知,用户随时可以看到哪些 app 在追踪位置。Map 和导航类 app 可以通过 allowsBackgroundLocationUpdates 配合新的 Info.plist key 来表明自己确实需要后台定位。
值得深挖的点
大致位置的精度范围
大致位置不是简单的「加噪声」,而是一个圆形区域,半径大约是一个城市街区到几个街区不等。CLLocation 的 horizontalAccuracy 会返回这个区域的半径。你的 app 需要检查这个值来判断拿到的是精确位置还是大致位置,然后决定是否需要请求临时精确授权。
临时精确授权的生命周期
临时精确授权只在当前 app 会话中有效。app 进入后台后被系统回收(或用户手动杀掉),下次启动时授权会回退到大致位置。这个设计确保了「一次性」的语义。你需要把需要精确定位的功能点标记出来,在使用前检查并请求临时授权。
代码片段
import CoreLocation
class LocationManager: NSObject, CLLocationManagerDelegate {
let manager = CLLocationManager()
override init() {
super.init()
manager.delegate = self
}
func requestLocationPermission() {
// 请求位置权限(iOS 14 默认可能给大致位置)
manager.requestWhenInUseAuthorization()
}
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
switch manager.authorizationStatus {
case .authorizedWhenInUse, .authorizedAlways:
if manager.accuracyAuthorization == .fullAccuracy {
// 精确定位已授权
manager.requestLocation()
} else {
// 只有大致位置,需要临时请求精确位置
requestTemporaryFullAccuracy()
}
case .notDetermined:
break
default:
break
}
}
func requestTemporaryFullAccuracy() {
// purposeKey 对应 Info.plist 中描述临时精确位置用途的 key
manager.requestTemporaryFullAccuracyAuthorization(
withPurposeKey: "PreciseLocationDescription"
) { error in
if let error = error {
print("临时精确位置请求失败: \(error)")
}
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
guard let location = locations.last else { return }
if location.horizontalAccuracy > 100 {
// 大致位置,精度超过 100 米
print("大致位置: \(location.coordinate), 精度: \(location.horizontalAccuracy)m")
} else {
// 精确位置
print("精确位置: \(location.coordinate), 精度: \(location.horizontalAccuracy)m")
}
}
}
<!-- Info.plist 中需要添加的 key -->
<key>NSLocationWhenInUseUsageDescription</key>
<string>需要获取您的位置来推荐附近的餐厅</string>
<key>NSLocationTemporaryUsageDescriptionDictionary</key>
<dict>
<key>PreciseLocationDescription</key>
<string>导航到目的地需要精确的位置信息</string>
</dict>
最佳实践
- 先适配大致位置。不要一上来就请求精确定位。大部分功能(天气、本地新闻、餐厅推荐)用大致位置就够了。只在真正需要精确定位的场景(导航、跑步记录)才请求临时精确授权。
- 检查
accuracyAuthorization而不是假设精确位置。以前拿到authorizedWhenInUse就意味着精确位置,iOS 14 不一定了。每次使用位置前都检查精度级别。 - 给用户解释为什么需要精确位置。临时精确授权的弹窗会显示你在 Info.plist 中填写的描述。写得具体一点,比如「导航到目的地需要精确位置」,而不是笼统的「需要位置权限」。
还有什么值得关注
- iOS 14 的位置权限弹窗新增了「只允许一次」选项,和 Android 的单次授权类似。
CLLocationManager新增了authorizationStatus的CLAccuracyAuthorization属性,可以独立检查精度授权状态。- 如果你的 app 在后台持续使用位置,iOS 14 会定期弹出通知告诉用户,用户可以选择降级权限。要确保 app 在权限降级后仍能优雅运行。