独立WatchOS应用中Core Location无法正常工作的问题排查
我正在开发一款依赖用户位置数据的独立WatchOS应用,调用CLLocationManager的requestWhenInUseAuthorization()方法后,Apple Watch上未弹出位置权限对话框,authorizationStatus一直返回notDetermined。
已经做过的排查:
- 在Info.plist中添加了
NSLocationWhenInUseUsageDescription键值对; - 把WatchOS App标记成了独立应用;
- 在Simulator里通过
Features -> Location -> Custom Location...设置了自定义坐标; - 开启了Simulator的定位服务,并且把应用的位置共享设为When Shared;
- 换到真实Apple Watch上运行,问题还是存在。
附上LocationManager.swift代码:
import CoreLocation class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate { private let manager = CLLocationManager() @Published var location: CLLocation? override init() { super.init() manager.delegate = self manager.requestWhenInUseAuthorization() manager.startUpdatingLocation() print("LocationManager initialized and requesting location") switch manager.authorizationStatus { case .notDetermined: print("Location authorization status: notDetermined") // <--- 一直返回这个 case .restricted: print("Location authorization status: restricted") case .denied: print("Location authorization status: denied") case .authorizedAlways: print("Location authorization status: authorizedAlways") case .authorizedWhenInUse: print("Location authorization status: authorizedWhenInUse") @unknown default: print("Location authorization status: unknown") } } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { if let firstLocation = locations.first { location = firstLocation manager.stopUpdatingLocation() print("Location updated: \(firstLocation)") } } func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { print("Failed to get location: \(error.localizedDescription)") } }
解决办法
1. 检查Info.plist的键是否加对地方
独立WatchOS应用的权限描述键必须加在Watch Extension的Info.plist里,不是Watch App的那个。很多人会误加到App的配置文件,导致权限请求根本不触发弹窗。
2. 用代理方法监听权限变化,别在初始化时直接查
你现在在init里直接打印authorizationStatus,但requestWhenInUseAuthorization()是异步的,这时候系统还没处理完请求,肯定返回notDetermined。得实现权限变更的代理方法,才能拿到真实的状态:
func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { switch manager.authorizationStatus { case .notDetermined: print("Location authorization status: notDetermined") case .restricted: print("Location authorization status: restricted") case .denied: print("Location authorization status: denied") case .authorizedAlways: print("Location authorization status: authorizedAlways") case .authorizedWhenInUse: print("Location authorization status: authorizedWhenInUse") // 权限过了再启动位置更新 manager.startUpdatingLocation() @unknown default: print("Location authorization status: unknown") } }
同时改init方法,把startUpdatingLocation()移掉,只留权限请求:
override init() { super.init() manager.delegate = self print("LocationManager initialized and requesting location") manager.requestWhenInUseAuthorization() }
只有权限授权成功后再去请求位置,不然也是白忙活。
3. 真机上检查系统权限设置
在Apple Watch上:
- 打开
设置 -> 隐私与安全性 -> 定位服务,确保全局定位是开的; - 找到你的应用,看看是不是之前误点了“永不允许”,要是拒绝过,得手动重置权限;
- 也可以在iPhone上的
Watch应用 -> 我的手表 -> 隐私与安全性 -> 定位服务里找到对应应用,重置权限后重启App再试。
4. 确认独立应用的配置没问题
在Xcode里:
- 选中WatchOS App的target,进
General标签,确认Supports Running Independently of iPhone已经勾选; - 去
Signing & Capabilities里看看,有没有冲突的权限或者后台模式,没用的后台模式最好删掉,避免干扰。
5. 模拟器测试的额外注意点
用Watch Simulator时:
- 确保
Simulator -> Features -> Location没选“None”,得选一个定位或者自定义坐标; - 要是之前在模拟器里拒绝过权限,去
Simulator -> Settings -> Privacy & Security -> Location Services找到应用,重置权限; - 重启模拟器和Xcode,清掉应用缓存再测。
内容的提问来源于stack exchange,提问作者Khaled
相关产品推荐
相关产品推荐

