locationManager(_:​did​Change​Authorization:​) 在应用首次运行时执行?

Posted

技术标签:

【中文标题】locationManager(_:​did​Change​Authorization:​) 在应用首次运行时执行?【英文标题】:locationManager(_:​did​Change​Authorization:​) executes when app first runs? 【发布时间】:2017-03-18 00:47:13 【问题描述】:

是否每次应用首次运行时都会调用 location​Manager(_:​did​Change​Authorization:​),即使未调用位置管理器方法 requestWhenInUseAuthorization() 或 startUpdatingLocation()?我正在尝试通过单击我在下面的@IBAction 中调用的按钮来报告位置:

@IBAction func findOutPressed(_ sender: UIButton) 
    getLocation()

我的 CoreLocation 代码在下面的扩展中:

extension ViewController: CLLocationManagerDelegate 
    
    // Called from findOutPressed to get location when button is clicked
    func getLocation() 
        let status = CLLocationManager.authorizationStatus()
        handleLocationAuthorizationStatus(status: status)
    
    
    // Respond to the result of the location manager authorization status
    func handleLocationAuthorizationStatus(status: CLAuthorizationStatus) 
        switch status 
        case .notDetermined:
            locationManager.requestWhenInUseAuthorization()
        case .authorizedWhenInUse, .authorizedAlways:
            locationManager.startUpdatingLocation()
        case .denied:
            print("I'm sorry - I can't show location. User has not authorized it")
        case .restricted:
            print("Access denied - likely parental controls are restricting use in this app.")
        
    
    
    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) 
        handleLocationAuthorizationStatus(status: status)
    
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) 
        
        let currentLocation = locations.last
        
        let labelText = "My location is: latitude = \((currentLocation?.coordinate.latitude)!), longitude = \((currentLocation?.coordinate.longitude)!)"
        
        resultLabel.text = labelText
        
        locationManager.stopUpdatingLocation()
    
    
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) 
        print("Dang, there was an error! Error: \(error)")
    

我发现 location​Manager(did​Change​Authorization:​) 正在立即执行,即使 @IBAction findOutPressed 没有被点击触发,并且结果正在我最初的空白中更新用户单击按钮之前的结果标签。我知道我可以设置一个标志来确定是否单击了按钮,从而防止标签过早更新,但我试图了解何时触发 location​Manager(_:​did​Change​Authorization)。苹果 说: “只要应用程序使用位置服务的能力发生变化,就会调用此方法。可能会发生变化,因为用户允许或拒绝为您的应用程序或整个系统使用位置服务。” 这似乎没有涵盖应用程序首次运行时触发的情况。我很感谢任何可以让我直接了解授权更改发生情况的人。抱歉,如果我错过了一些基本的东西。 谢谢!

【问题讨论】:

【参考方案1】:

didChangeAuthorization 在创建 CLLocationManager 时被调用,所以即使这样也会触发:

var locationManager = CLLocationManager()
// ...
locationManager?.delegate = self
// ...
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) 
    print( "authorization checked..." )

所以您可能正在 AppDelegate 的顶部设置和初始化您的 locationManager?那会触发它。然后发生的事情是 didChangeAuthorization 开始更新位置,然后在实际点击按钮之前调用您的 didUpudateLocation。

也许在 findOutPressed() 中将 locationManager 声明为可选且仅 init 例如:

// class var:
var locationManager:CLLocationManager?location managers,
// ...
@IBAction func findOutPressed(_ sender: UIButton) 
    locationManager = CLLocationManager()
    locationManager?.delegate = self

    getLocation()

【讨论】:

谢谢!这有效 - 非常感谢!我还注意到另一件奇怪的事情:如果我在模拟器中更改位置:例如从自定义位置到 Apple,Apple 位置不会在随后的点击中显示。如果我退出模拟器并重新运行应用程序,我确实会看到更改生效,但如果我切换回我的自定义位置,我必须在看到更改之前执行相同的应用程序退出并重新运行。这是标准行为还是发生了其他奇怪的事情?

以上是关于locationManager(_:​did​Change​Authorization:​) 在应用首次运行时执行?的主要内容,如果未能解决你的问题,请参考以下文章

区块链应用系列 - DID

区块链应用系列 - DID

不能调用 locationManager(_::didUpdateLocations:)

没有网络时不调用 CLLocationManagerDelegate -locationManager(_:startMonitoring:)

tomcat 启动报错 404——did not find a matching property

error: ‘_beginthreadex‘ undeclared (first use in this function); did you mean ‘SDL_beginthread‘?(代码片