如何存储从reverseGeocodeLocation()方法(异步任务)检索到的数据(到全局变量中)?

时间:2018-09-11 01:54:18

标签: ios swift asynchronous clgeocoder

首先,我有一个全局变量:

var userCity : String? 

使用reverseGeocodeLocation()从用户的位置获取城市名称,我试图将该城市名称信息存储到userCity全局变量中。我知道您不能简单地从异步任务中返回数据。相反,您将不得不通过一个块传回。这是我看完其他StackOverflow帖子到目前为止的内容:

//get user's location
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    let location = locations[locations.count - 1]

    if location.horizontalAccuracy > 0 {
        locationManager.stopUpdatingLocation()
        locationManager.delegate = nil

        reverseCoordinatesToCity(location: location) { (city) in
            self.userCity = city
        }
    }
}

func reverseCoordinatesToCity(location: CLLocation, completion: @escaping (_ city: String?) -> Void) {

    CLGeocoder().reverseGeocodeLocation(location, completionHandler: {(placemarks, error) -> Void in
        if (error != nil) {
            print("Reverse geocoder failed with an error: " + (error?.localizedDescription)!)
            completion("")
        } else if (placemarks?.count)! > 0 {
            let pm = placemarks![0] as CLPlacemark
            completion(pm.locality!)
        } else {
            print("Problems with the data received from geocoder.")
            completion("")
        }
    })
}

当我尝试以其他方法打印userCity时。例如:

func someFunction() {
    print(userCity!)
}

没有打印任何内容,似乎userCity为零。我花了将近三个小时来尝试解决这个问题。我的主要目标是使用segue将此数据传递到另一个ViewController。

感谢您的帮助。谢谢。

1 个答案:

答案 0 :(得分:0)

正如@rmaddy所说,city准备就绪时您没有使用它。解决该问题的方法是从CLGeocoder回调中获取视图控制器逻辑。如果您不想再使用位置管理器,也值得将其设置为nil,因为stopUpdatingLocations()并不总是停止位置更新而已。

func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations[locations.count - 1]

if location.horizontalAccuracy > 0 {
    locationManager.stopUpdatingLocation()
    locationManager.delegate = nil
    locationManager = nil //this makes sure you don't get more updates

    reverseCoordinatesToCity(location: location)
    }
}

func reverseCoordinatesToCity(location: CLLocation) {

CLGeocoder().reverseGeocodeLocation(location, completionHandler: {(placemarks, error) -> Void in
    if (error != nil) {
        print("Reverse geocoder failed with an error: " + (error?.localizedDescription)!)
    } else if (placemarks?.count)! > 0 {
        let pm = placemarks![0] as CLPlacemark
        city = pm.locality!
        //use city here with your view controllers
    } else {
        print("Problems with the data received from geocoder.")
    }
})
}