如何向系统方法添加闭包?

How to add a closure to a system method?

我目前正在创建一个使用 CLLocationManager 的应用程序,但我没有在应用程序委托中提示询问位置权限,而是在按下 "check in" 的按钮时执行它。我正在尝试创建一个闭包,允许用户在他们接受允许定位服务后签入。截至目前,在用户接受定位服务后,签入它们的代码尚未激活,因为在用户实际接受定位服务之前会检查定位服务是否已启用。这是我的代码:

typealias CompletionHandler = (success:Bool) -> Void

func askLocationPermission (completionHandler: CompletionHandler) {
    self.locationsManager.requestWhenInUseAuthorization()
}

@IBAction func checkInButtonPressed(sender: AnyObject) {

    askLocationPermission { (success) in
        if CLLocationManager.locationServicesEnabled() {
            self.locationsManager.delegate = self

            if let location = self.locationsManager.location {
                self.currentUserLatitude = location.coordinate.latitude
                self.currentUserLongitude = location.coordinate.longitude

                print("This is the current latitide: \(location.coordinate.latitude)")
                print("This is the current longitude: \(location.coordinate.longitude)")

                self.checkInLocation(
                    userInfo.sharedInstance.getAccessToken(), 
                    id: userInfo.sharedInstance.getMemberID()!, 
                    latitude: self.currentUserLatitude!, 
                    radius: 0.3, 
                    longitude: self.currentUserLongitude!)
            }
        }  
    }
}

您可以只使用 CLLocationManager 提供的委托结构,而不是添加闭包。这里是 documentation for CLLocationManager (as well as a larger tutorial on how to use it) and here is documentation for the delegate.

首先,按下按钮时,我们要注册为委托人,以便我们从 CLLocationManager 获取所有更新。这样,CLLocationManager 会告诉我们授权状态何时更改以及何时获得新位置。注册为受托人后,我们检查授权状态。如果还没有决定,我们会征求用户的许可。否则我们要么没有访问权限,要么用户已经授予权限,我们只是获取他们的位置!

@IBAction func checkInButtonPressed(sender: AnyObject) {

    // Set us as a delegate so the manager updates us
    self.locationsManager.delegate = self

    // Check our authorization status and request access if we need
    if CLLocationManager.authorizationStatus() ==  kCLAuthorizationStatusNotDetermined {
        // User hasn't given permission yet, ask for permission
        self.locationsManager.requestWhenInUseAuthorization()
    } else if CLLocationManager.authorizationStatus() ==  kCLAuthorizationStatusRestricted || CLLocationManager.authorizationStatus() ==  kCLAuthorizationStatusDenied {
        // Handle denied access
    } else {
        // We have access! Start listening now
        self.locationsManager.startUpdatingLocation()
    }
}

接下来,我们要处理用户尚未授予我们访问权限的情况,我们向他们显示权限弹出窗口。他们可以点击是(或否),所以我们想处理这两种情况。就像上面一样,如果他们点击是,就开始获取位置!

// Called when the user changes the authorization status- in this case
//  this will change when the user taps yes/no in the permission popup
func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
    if CLLocationManager.authorizationStatus() ==  kCLAuthorizationStatusRestricted || CLLocationManager.authorizationStatus() ==  kCLAuthorizationStatusDenied {
        // Handle denied access
    } else {
        // We have access! Start listening now
        self.locationsManager.startUpdatingLocation()
    }
}

我们终于可以开始做事了! CLLocationManager 每当它到达新位置时调用它,所以这是签到的最佳时机!获得良好的锁定可能需要一段时间,因此您可能需要提醒 checkInButtonPressed 中的用户您正在处理它并会很快更新它们。

// Called every time the locationManager gets a new location
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {

    self.currentUserLatitude = manager.coordinate.latitude
    self.currentUserLongitude = manager.coordinate.longitude

    print("This is the current latitide: \(location.coordinate.latitude)")
    print("This is the current longitude: \(location.coordinate.longitude)")

    self.checkInLocation(
        userInfo.sharedInstance.getAccessToken(), 
        id: userInfo.sharedInstance.getMemberID()!, 
        latitude: self.currentUserLatitude!, 
        radius: 0.3, 
        longitude: self.currentUserLongitude!)
}