CLLocationManager AuthorizationStatuscallback?

在我的应用程序中,我有一个名为“发现”的选项卡。 “发现”选项卡将使用用户当前的位置在他们附近find“东西”。 我没有向用户展示一个通用的授权请求(通常是基于研究而被拒绝),而是向用户展示了一个解释我们要求的模式。 如果他们说是,那么popup实际的授权消息。

但是,用户仍然可以select不提示。 有没有办法添加callback的提示,以便一旦用户select一个选项,我可以看到他们接受或拒绝?

我试过这个:

func promptForLocationDataAccess() { locationManager.requestWhenInUseAuthorization() println("test") } 

正如所料,“println”在请求提示出现的同时执行,所以我不能这样做。

问题是,如果用户select不使用位置数据,则服务的内容将不同于他们已经接受的内容。

理想情况下,我希望有某种callback,但是我会采取任何逻辑的方向!

您可以使用locationManager:didChangeAuthorizationStatus: CLLocationManagerDelegate方法作为sorting的“callback”。

 - (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { if (status == kCLAuthorizationStatusDenied) { // The user denied authorization } else if (status == kCLAuthorizationStatusAuthorized) { // The user accepted authorization } } 

而在Swift(由用户Michael Marvick提供的更新,由于某种原因被拒绝…):

 func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) { if (status == CLAuthorizationStatus.denied) { // The user denied authorization } else if (status == CLAuthorizationStatus.authorizedAlways) { // The user accepted authorization } } 

当位置的授权状态改变时,委托方法didChangeAuthorizationStatus:将被调用。

在安装应用程序后第一次调用requestWhenInUseAuthorization时,将使用状态kCLAuthorizationStatusNotDetermined (0)调用委托方法。

如果用户拒绝位置服务访问,那么委托方法将再次以状态kCLAuthorizationStatusDenied (2)被调用。

如果用户批准位置服务访问,那么将根据请求的权限再次调用委托方法,状态为kCLAuthorizationStatusAuthorizedAlways (3)或kCLAuthorizationStatusAuthorizedWhenInUse (4)。

在后续执行应用程序时,根据设备设置中应用程序的位置服务权限的当前状态调用requestWhenInUseAuthorization后,委托方法将接收状态kCLAuthorizationStatusDeniedkCLAuthorizationStatusAuthorizedAlways / kCLAuthorizationStatusAuthorizedWhenInUse

Swift 3

 func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { if (status == CLAuthorizationStatus.denied) { // The user denied authorization } else if (status == CLAuthorizationStatus.authorizedAlways) { // The user accepted authorization } } 

这个解决scheme在所有的情况下都不是最好的,但是对我来说,所以我想分享一下:

 import Foundation import CoreLocation class LocationManager: NSObject, CLLocationManagerDelegate { static let sharedInstance = LocationManager() private var locationManager = CLLocationManager() private let operationQueue = OperationQueue() override init(){ super.init() //Pause the operation queue because // we don't know if we have location permissions yet operationQueue.isSuspended = true locationManager.delegate = self } ///When the user presses the allow/don't allow buttons on the popup dialogue func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { //If we're authorized to use location services, run all operations in the queue // otherwise if we were denied access, cancel the operations if(status == .authorizedAlways || status == .authorizedWhenInUse){ self.operationQueue.isSuspended = false }else if(status == .denied){ self.operationQueue.cancelAllOperations() } } ///Checks the status of the location permission /// and adds the callback block to the queue to run when finished checking /// NOTE: Anything done in the UI should be enclosed in `DispatchQueue.main.async {}` func runLocationBlock(callback: @escaping () -> ()){ //Get the current authorization status let authState = CLLocationManager.authorizationStatus() //If we have permissions, start executing the commands immediately // otherwise request permission if(authState == .authorizedAlways || authState == .authorizedWhenInUse){ self.operationQueue.isSuspended = false }else{ //Request permission locationManager.requestAlwaysAuthorization() } //Create a closure with the callback function so we can add it to the operationQueue let block = { callback() } //Add block to the queue to be executed asynchronously self.operationQueue.addOperation(block) } } 

现在,每当你想使用位置信息,只是围绕着它:

 LocationManager.sharedInstance.runLocationBlock { //insert location code here } 

所以,只要你尝试使用位置信息,就会检查授权状态。 如果您还没有权限,则会请求权限并等待用户按下“允许”button或“不允许”button。 如果按下“允许”button,位置数据的任何请求将在不同的线程上处理,但是如果按下“不允许”button,所有的位置请求将被取消。