CLLocationManager AuthorizationStatus回调?

mat*_*ill 26 ios swift

在我的应用程序中,我有一个名为"发现"的标签."发现"选项卡将使用用户的当前位置来查找附近的"内容".我没有向用户提供通用的授权请求(通常会根据研究得到拒绝),而是向用户提供一个解释我们要求的模式.如果他们说是,则会弹出实际的授权消息.

但是,用户仍然可以选择不提示.有没有办法在提示中添加回调,以便一旦用户选择了一个选项,我可以看到他们是否接受或拒绝了?

我试过这个:

func promptForLocationDataAccess() {
    locationManager.requestWhenInUseAuthorization()
    println("test")
}
Run Code Online (Sandbox Code Playgroud)

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

问题是,如果用户选择不使用位置数据,则所提供的内容将与他们已接受的内容不同.

理想情况下,我希望有某种回调,但我会在这一点上采取任何合理的方向!

Lyn*_*ott 53

您可以将该 方法用作各种"回调".locationManager:didChangeAuthorizationStatus: CLLocationManagerDelegate

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

在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
    } 
}
Run Code Online (Sandbox Code Playgroud)


use*_*459 6

斯威夫特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
    } 
}
Run Code Online (Sandbox Code Playgroud)


Pau*_*w11 5

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

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

如果用户拒绝位置服务访问,则将再次使用status kCLAuthorizationStatusDenied(2)调用委托方法.

如果用户批准位置服务访问,则将再次使用status kCLAuthorizationStatusAuthorizedAlways(3)或kCLAuthorizationStatusAuthorizedWhenInUse(4)调用委托方法,具体取决于所请求的权限.

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


tdo*_*don 5

这个解决方案并不是在所有情况下都是最好的,但它对我有用,所以我想我会分享:

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)
    }
}
Run Code Online (Sandbox Code Playgroud)

现在每次你想使用位置信息时,只需用这个包围它:

LocationManager.sharedInstance.runLocationBlock {
    //insert location code here
}
Run Code Online (Sandbox Code Playgroud)

因此,每当您尝试使用位置信息时,都会检查授权状态。如果您还没有权限,它会请求权限并等待用户按下“允许”按钮或“不允许”按钮。如果按下“允许”按钮,任何对位置数据的请求都将在单独的线程上处理,但如果按下“不允许”按钮,则所有位置请求都将被取消。