Swift 更改应用程序位置设置后,重新评估正在运行的应用程序中的CLLocationManager.authorizationStatus

Swift 更改应用程序位置设置后,重新评估正在运行的应用程序中的CLLocationManager.authorizationStatus,swift,closures,alert,cllocationmanager,Swift,Closures,Alert,Cllocationmanager,多亏了下面Thomas的建议,我已经修改了原始请求的代码。我想知道我是否在尝试做一些不可能的事情,或者,如果不是,我如何才能做到这一点 如果用户没有授权位置服务,我会通过一个带有“打开设置”按钮的警报提示他们更改应用程序的位置设置。这很有效。但在从设置返回应用程序时,我想确认是否进行了更改并激活位置服务。这能做到吗?下面的闭包成功地让用户访问应用程序的设置,用户可以进行更改,用户也可以返回,但是当用户按下“打开设置”时,闭包会触发,这是在设置更改之前。顺便说一句:如果有更好的方法来处理轻推用户批

多亏了下面Thomas的建议,我已经修改了原始请求的代码。我想知道我是否在尝试做一些不可能的事情,或者,如果不是,我如何才能做到这一点

如果用户没有授权位置服务,我会通过一个带有“打开设置”按钮的警报提示他们更改应用程序的位置设置。这很有效。但在从设置返回应用程序时,我想确认是否进行了更改并激活位置服务。这能做到吗?下面的闭包成功地让用户访问应用程序的设置,用户可以进行更改,用户也可以返回,但是当用户按下“打开设置”时,闭包会触发,这是在设置更改之前。顺便说一句:如果有更好的方法来处理轻推用户批准应用程序当前未经授权的位置优先权,我将非常感谢您的建议。谢谢

locationManager.requestWhenInUseAuthorization() // request authorization

let authStatus = CLLocationManager.authorizationStatus()

switch authStatus {
    case .denied:
        let alertController = UIAlertController(title: "Background Location Access Disabled", message: "In order to show the location weather forecast, please open this app's settings and set location access to 'While Using'.", preferredStyle: .alert)
        alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
        alertController.addAction(UIAlertAction(title: "Open Settings", style: .`default`, handler: { action in
            if #available(iOS 10.0, *) {
                let settingsURL = URL(string: UIApplicationOpenSettingsURLString)!
                UIApplication.shared.open(settingsURL, options: [:], completionHandler: {(success) in
                    print("*** Success closure fires")
                    let newAuthStatus = CLLocationManager.authorizationStatus()
                    switch newAuthStatus {
                    case .authorizedWhenInUse:
                        self.locationManager.startUpdatingLocation()
                    default:
                        print("Not .authorizedWhenInUse")
                    }
                })
            } else {
                if let url = NSURL(string:UIApplicationOpenSettingsURLString) {
                    UIApplication.shared.openURL(url as URL)
                }
            }
        }))
        self.present(alertController, animated: true, completion: nil)

    case .authorizedWhenInUse, .authorizedAlways:
        locationManager.startUpdatingLocation()
    case .restricted :
        print("App is restricted, likely via parental controls.")
    default:
        print("UH!! WHAT OTHER CASES ARE THERE? ")
    }

我认为这里的扩展代码实现了我想要的——一个简单的get位置,但它处理所有授权状态情况: -.未确定:未使用授权时请求 -.授权:StartupDating地点 -.denied:向用户提示使用UIApplicationOpenSettingsURLString打开应用程序隐私/位置设置的警报,以便用户进行更改。在didUpdateLocations中获取返回应用程序的新状态,以便在更新设置后捕获用户位置 -.restricted-显示一个警报,提示用户与家长或系统管理员联系以解除应用程序限制

如果出现故障或错误,警报还显示w/错误代码

只需为locationManager和currentLocation设置实例变量

let locationManager = CLLocationManager()
var currentLocation: CLLocation!
并在viewDidLoad中设置委托&调用getLocation()

locationManager.delegate=self getLocation()

希望这是合理的,但最受欢迎的是关于更好的方法的建议。希望它能帮助一些人,因为我很难在Swift 3&comprehensive中找到一些东西。再次感谢你,托马斯

扩展视图控制器:CLLocationManagerDelegate{

func getLocation() {

    let status = CLLocationManager.authorizationStatus()

    handleLocationAuthorizationStatus(status: 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")
        statusDeniedAlert()
    case .restricted:
        showAlert(title: "Access to Location Services is Restricted", message: "Parental Controls or a system administrator may be limiting your access to location services. Ask them to.")
    }
}

func showAlert(title: String, message: String) {
    let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)

    let defaultAction = UIAlertAction(title: "OK", style: .default, handler: nil)

    alertController.addAction(defaultAction)

    present(alertController, animated: true, completion: nil)
}

func statusDeniedAlert() {
    let alertController = UIAlertController(title: "Background Location Access Disabled", message: "In order to show the location weather forecast, please open this app's settings and set location access to 'While Using'.", preferredStyle: .alert)
    alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
    alertController.addAction(UIAlertAction(title: "Open Settings", style: .`default`, handler: { action in
        if #available(iOS 10.0, *) {
            let settingsURL = URL(string: UIApplicationOpenSettingsURLString)!
            UIApplication.shared.open(settingsURL, options: [:], completionHandler: nil)
        } else {
            if let url = NSURL(string:UIApplicationOpenSettingsURLString) {
                UIApplication.shared.openURL(url as URL)
            }
        }
    }))
    self.present(alertController, animated: true, completion: nil)
}

func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
    handleLocationAuthorizationStatus(status: status)
}

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    if let currentLocation = locations.last {
        print("My coordinates are: \(currentLocation.coordinate.latitude), \(currentLocation.coordinate.longitude)")
        locationManager.stopUpdatingLocation()
        updateUserInterface()
    }
}

func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
    showAlert(title: "Location Access Failure", message: "App could not access locations. Loation services may be unavailable or are turned off. Error code: \(error)")
}

}

我想你误解的是
现在的
方法。当视图控制器完成呈现时,将触发完成。从您的描述中我有点不清楚,但听起来您希望在用户选择一个警报选项后触发此操作,因此此代码应该位于UIAlertAction的一个完成处理程序中。谢谢,Thomas。这很有帮助。当用户点击“打开设置”按钮时,我可以移动我的关闭并让它执行。但我想知道我是不是在问不可能的事。我希望在用户通过:uiApplicationOpenSettingSurlsString从应用程序设置返回应用程序时再次测试授权。当用户从更改设置返回并检查我们现在是否有授权时,是否可能以某种方式触发代码?再次感谢你的建议!