Это происходит потому, что reverseGeocodeLocation
возвращается сразу, а его обработчик завершения запускается позже. Это означает, что значение ret
может быть пустым, когда оно помещается в основную очередь. Вы должны отправить на главную из обратного вызова, например:
func coordinateToString(lat: Double, long: Double, completion: @escaping (String) -> ()) {
let geoCoder = CLGeocoder()
let location = CLLocation(latitude: lat, longitude: long)
var ret = ""
geoCoder.reverseGeocodeLocation(location, completionHandler:
{
placemarks, error -> Void in
guard let placeMark = placemarks?.first else { return }
if let zip = placeMark.postalCode, let town = placeMark.subAdministrativeArea
{
let toAppend = "\(zip)" + " \(town)"
ret = toAppend
DispatchQueue.main.async {
completion(ret)
}
}
})
Конечно, с учетом этого сценария вам необходимо соответствующим образом обрабатывать ошибки. Еще лучше, используйте defer
, таким образом вызывается завершение независимо от того, что происходит:
func coordinateToString(lat: Double, long: Double, completion: @escaping (String) -> ()) {
let geoCoder = CLGeocoder()
let location = CLLocation(latitude: lat, longitude: long)
var ret = ""
geoCoder.reverseGeocodeLocation(location, completionHandler:
{
defer {
DispatchQueue.main.async {
completion(ret)
}
}
placemarks, error -> Void in
guard let placeMark = placemarks?.first else { return }
if let zip = placeMark.postalCode, let town = placeMark.subAdministrativeArea
{
let toAppend = "\(zip)" + " \(town)"
ret = toAppend
}
})