locationManagerDidChangeAuthorization 未被调用

问题描述 投票:0回答:1

我用单例模式实现了一个符合

CLLocationManagerDelegate
的类。调用
requestWhenInUseAuthorization
(即下面代码中的
requestPermission()
)会提示用户接受,如预期的那样。但是,一旦用户点击“允许一次”,并不总是会调用
locationManagerDidChangeAuthorization(_ manager: CLLocationManager)
。 当它被调用时我没有发现任何模式,当它不被调用时,它似乎非常不一致(它永远不会在第一次调用每个新的应用程序下载时被调用。这种情况在真实设备和模拟器上都会发生。

当我实现一个函数

forceInit()
并在我的应用程序中很早就调用它时,一切都运行良好。因此,我认为这是由于单例被延迟初始化引起的,并且如果单例初始化“太晚”,则委托函数不会被调用。

我做错了什么吗?为什么我需要提前初始化单例,当

requestPermission()
调用需要时无论如何都会初始化单例?


class LocationService: NSObject, CLLocationManagerDelegate {
    
    static var shared: LocationService = LocationService()
    
    @Published private(set) var authorizationStatus: CLAuthorizationStatus
    
    private let clLocationManager: CLLocationManager
    
    public override init() {
        clLocationManager = CLLocationManager()
        authorizationStatus = clLocationManager.authorizationStatus
        
        super.init()
        
        clLocationManager.delegate = self
        clLocationManager.desiredAccuracy = kCLLocationAccuracyBest
        clLocationManager.startUpdatingLocation()
    }
    
    func forceInit() { // why do I need this? I would rather not explicitly initialise...
        authorizationStatus = clLocationManager.authorizationStatus
    }
    
    func requestPermission() {
        self.clLocationManager.requestWhenInUseAuthorization()
    }

    func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
        print("AAA NEW AUTH: \(manager.authorizationStatus)") // not printed unless forceInit() is called right on app launch
        self.authorizationStatus = manager.authorizationStatus
        // TODO
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard let newLocation: CLLocation = locations.first else { return }
        
        // do sth
    }
}
ios swift
1个回答
0
投票

这也发生在我身上。 对我来说,答案与 CLLocationManager 文档中这个模糊的细节有关:

Core Location 从初始化 CLLocationManager 的线程调用运行循环上委托对象的方法。该线程本身必须有一个活动的运行循环,就像应用程序主线程中的运行循环一样。

我在侧线程中运行大部分初始化,以便我可以同时为启动屏幕设置动画。 一旦侧线程消失,位置管理器委托调用也会消失。

所以我的解决方案是确保在主线程中初始化 CLLocationManager。

© www.soinside.com 2019 - 2024. All rights reserved.