独立watchOS应用陷入Core Location授权循环问题求助
独立watchOS应用Always定位权限请求循环问题
问题背景
我正在开发一款独立(standalone)watchOS应用,需要前台和后台均能获取精确位置数据(即需「Always」权限)。已完成以下配置:
- 使用Xcode 14.3创建全新独立应用
- 为应用目标启用「location updates」后台模式
- 在
Info.plist中声明NSLocationWhenInUseUsageDescription和NSLocationAlwaysAndWhenInUseUsageDescription两个权限描述键
代码实现
ContentView代码
import SwiftUI struct ContentView: View { @StateObject var viewModel = ViewModel() var body: some View { VStack { Button(action: { viewModel.startLocationUpdates() }) { Text("Start location updates") } Button(action: { viewModel.stopLocationUpdates() }) { Text("Stop location updates") } } .disabled(viewModel.locationUpdateManager.locationAccessGranted == false) .padding() } }
ViewModel代码
import Foundation extension ContentView { @MainActor final class ViewModel: ObservableObject { let locationUpdateManager = LocationUpdateManager.shared func startLocationUpdates() { locationUpdateManager.startLocationUpdates() } func stopLocationUpdates() { locationUpdateManager.stopLocationUpdates() } } }
LocationUpdateManager单例代码
import CoreLocation class LocationUpdateManager: NSObject, CLLocationManagerDelegate, ObservableObject { public static let shared = LocationUpdateManager() @Published var locationAccessGranted: Bool = false private var locationManager = CLLocationManager() private override init() { super.init() locationManager.allowsBackgroundLocationUpdates = true locationManager.delegate = self // triggers callback to locationManagerDidChangeAuthorization(_:) } func startLocationUpdates() { locationManager.startUpdatingLocation() } func stopLocationUpdates() { locationManager.stopUpdatingLocation() } // MARK: - CLLocationManagerDelegate methods func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { locationAccessGranted = false switch manager.authorizationStatus { case .notDetermined: print("User has not chosen whether the app can use location services or not; requesting \"when in use\" authorization now") manager.requestWhenInUseAuthorization() case .authorizedWhenInUse: print("User granted \"when in use\" authorization; requesting \"always\" authorization now") manager.requestAlwaysAuthorization() case .authorizedAlways: print("User granted \"always\" authorization") switch manager.accuracyAuthorization { case .fullAccuracy: print("User granted access to location data with full accuracy") locationAccessGranted = true case .reducedAccuracy: print("User granted access to location data with reduced accuracy") default: print("Warning: unhandled CLAccuracyAuthorization value!") } case .denied: print("User denied access to location services or they are disabled globally in Settings") case .restricted: print("App is not authorized to use location services and the user is restricted from changing this for some reason") default: print("Warning: unhandled CLAuthorizationStatus value!") } } func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) { print("Location manager reported an error: \(error.localizedDescription)") } func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { guard let location = locations.last else { return } print(location.debugDescription) } }
测试现象
在运行watchOS 9.4的Apple Watch Ultra实体设备和Apple Watch Series 8模拟器(通过iPhone配对)上测试,出现以下循环问题:
- 首次启动应用,
locationManagerDidChangeAuthorization(_:)回调触发,状态为.notDetermined,请求「When In Use」授权,手表弹窗选择「Allow While Using App」; - 回调再次触发,状态变为
.authorizedWhenInUse,请求「Always」授权,手表弹窗选择「Change to Always Allow」; - 回调触发
.authorizedAlways状态,但随即又触发一次回调,状态变回.notDetermined,陷入循环。
此时查看手表设置Privacy & Security -> Location Services -> MyApp,发现「Ask or When I Share」被选中,且所有设置不可修改;而配对iPhone的设置中,该应用的定位权限可修改,将其改为「Always」后,手表端应用不再循环弹窗。
更新发现
- 部署到独立的Apple Watch Ultra模拟器时,应用运行正常,授权后无循环问题;
- 部署到「Apple Watch Ultra (49 mm) via iPhone 14 Pro Max」模拟器或实体配对手表时,问题依旧。怀疑该问题与手表尝试使用配对iPhone的定位数据有关,寻求原因及解决方案。
内容的提问来源于stack exchange,提问作者bmt22033
相关产品推荐
相关产品推荐

