【问题标题】:Swift LocationManager didChangeAuthorizationStatus Always CalledSwift LocationManager didChangeAuthorizationStatus 总是被调用
【发布时间】:2015-07-18 08:05:47
【问题描述】:

我有一个实现CLLocationManagerDelegate 的视图控制器。我创建了一个 CLLocationManager 变量:

let locationManager = CLLocationManager()

然后在viewDidLoad,我设置属性:

// Set location manager properties
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationManager.distanceFilter = 50

问题是在我检查授权状态之前,函数就被调用了。

func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
    if (status == .AuthorizedWhenInUse) {
        // User has granted autorization to location, get location
        locationManager.startUpdatingLocation()
    }
}

谁能告诉我这是什么原因造成的?

【问题讨论】:

    标签: ios swift cllocationmanager


    【解决方案1】:

    - locationManager:didChangeAuthorizationStatus:CLLocationManager 初始化后不久被调用。

    如果需要,您可以在委托方法中请求授权:

    func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
        switch status {
        case .notDetermined:
            locationManager.requestAlwaysAuthorization()
            break
        case .authorizedWhenInUse:
            locationManager.startUpdatingLocation()
            break
        case .authorizedAlways:
            locationManager.startUpdatingLocation()
            break
        case .restricted:
            // restricted by e.g. parental controls. User can't enable Location Services
            break
        case .denied:
            // user denied your app access to Location Services, but can grant access from Settings.app
            break
        default:
            break
        }
    }
    

    请注意,如果您希望这样做,您需要“及时”分配委托。

    如果您会以某种方式延迟委托分配,例如通过异步设置,您可能会错过对- locationManager:didChangeAuthorizationStatus: 的初始调用。

    【讨论】:

    • 非常感谢。我没有意识到它在初始化后被调用。
    • 感谢您的回答。苹果文档需要使用此信息进行更新。
    • 这对我来说似乎是一个错误,我很难将其描述为授权状态的didChange。这种行为会影响编写对授权状态的实际变化做出反应的代码。
    • @turingtested 不幸的是,不能完全忽略此功能,因为它提供了跟踪授权状态更改的最佳方式。如果用户将应用程序设置为后台,更改位置权限,然后重新打开应用程序,则该功能将按预期方式工作。问题是该函数也会在 CLLocationManager 初始化时被调用,这真的没有意义而且很不幸。
    • 如果这对某人也不起作用。在 ios14 中不再调用此函数,因为它已被弃用。使用:func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) { if #available(iOS 14.0, *) { switch manager.authorizationStatus {...} } }
    【解决方案2】:

    其他答案可能会引入新的不良行为。

    你可以添加一个布尔值和一个守卫来防止第一次调用,一些 cmets 解释了这个错误:

    var firstTimeCalled = true
    
    // ...    
    
    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
    
        guard !firstTimeCalled else {
            firstTimeCalled = false
            return
        }
    
        // ... send status to listeners
    }
    

    【讨论】:

      【解决方案3】:

      斯威夫特 3

      func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
              switch status {
              case .notDetermined:
                  manager.requestAlwaysAuthorization()
                  break
              case .authorizedWhenInUse:
                  manager.startUpdatingLocation()
                  break
              case .authorizedAlways:
                  manager.startUpdatingLocation()
                  break
              case .restricted:
                  // restricted by e.g. parental controls. User can't enable Location Services
                  break
              case .denied:
                  // user denied your app access to Location Services, but can grant access from Settings.app
                  break
              }
          }
      

      【讨论】:

      • 当我尝试在 swift 4.
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-16
      • 2017-09-14
      • 2012-02-19
      • 2020-08-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多