Как сохранить данные (в глобальную переменную), полученные из метода reverseGeocodeLocation () (асинхронная задача)? - PullRequest
0 голосов
/ 11 сентября 2018

Сначала у меня есть глобальная переменная:

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 равен нулю.Я провел почти три часа, пытаясь понять это.Моя главная цель - передать эти данные в другой ViewController с помощью segue.

Любая помощь приветствуется.Спасибо.

1 Ответ

0 голосов
/ 11 сентября 2018

Как сказал @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.")
    }
})
}
...