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

独立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配对)上测试,出现以下循环问题:

  1. 首次启动应用,locationManagerDidChangeAuthorization(_:)回调触发,状态为.notDetermined,请求「When In Use」授权,手表弹窗选择「Allow While Using App」;
  2. 回调再次触发,状态变为.authorizedWhenInUse,请求「Always」授权,手表弹窗选择「Change to Always Allow」;
  3. 回调触发.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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 00:47:36