Функция координат iOS Swift возвращает ноль

Я работаю над функцией преобразования города (строки) в координаты. Однако, когда я вызываю функцию, я получаю в результате "(0.0, 0.0)". Это должны быть широта и долгота.

Пожалуйста, помогите мне. Спасибо!

Это функция

func getCoordinates(huidigeLocatie: String) -> (lat: CLLocationDegrees, long: CLLocationDegrees) {

    var lat:CLLocationDegrees
    var long:CLLocationDegrees

    var geocoderHuidigeLocatie = CLGeocoder()

    geocoderHuidigeLocatie.geocodeAddressString(huidigeLocatie, completionHandler:
        {(placemarks: [AnyObject]!, error: NSError!) in

            if error != nil {

                println("Geocode failed with error: \(error.localizedDescription)")

            } else if placemarks.count > 0 {

                let placemark = placemarks[0] as CLPlacemark
                let location = placemark.location

                var lat = location.coordinate.latitude
                var long = location.coordinate.longitude

            }
    })

    return (lat: CLLocationDegrees(), long: CLLocationDegrees())
}

person Nick Groeneveld    schedule 04.01.2015    source источник
comment
Я предполагаю, что если вы регистрируете lat и long в тесте else if, это работает? Тогда ваша проблема может быть связана с тем, что она асинхронная (как указано в документе).   -  person Larme    schedule 04.01.2015
comment
Я отлаживал его, и оказалось, что он даже не запускает оператор if. Я не знаю, почему это так. Леонардо, как мне это исправить?   -  person Nick Groeneveld    schedule 04.01.2015


Ответы (2)


Здесь есть две проблемы:

  1. Вы хотите вернуть фактические переменные lat и long, а не CLLocationDegrees().

  2. Более тонкая проблема заключается в том, что вы вызываете функцию, которая возвращает свои результаты асинхронно, поэтому вы не можете вернуть значения немедленно. Вместо этого вы можете использовать свой собственный шаблон завершенияHandler.

Например:

func getCoordinates(huidigeLocatie: String, completionHandler: (lat: CLLocationDegrees!, long: CLLocationDegrees!, error: NSError?) -> ()) -> Void {

    var lat:CLLocationDegrees
    var long:CLLocationDegrees

    var geocoderHuidigeLocatie = CLGeocoder()

    geocoderHuidigeLocatie.geocodeAddressString(huidigeLocatie) { (placemarks: [AnyObject]!, error: NSError!) in

        if error != nil {

            println("Geocode failed with error: \(error.localizedDescription)")

            completionHandler(lat: nil, long: nil, error: error)

        } else if placemarks.count > 0 {

            let placemark = placemarks[0] as CLPlacemark
            let location = placemark.location

            let lat = location.coordinate.latitude
            let long = location.coordinate.longitude

            completionHandler(lat: lat, long: long, error: nil)
        }
    }
}

И вы бы назвали это так:

getCoordinates(string) { lat, long, error in
    if error != nil { 
        // handle the error here 
    } else {
        // use lat, long here
    }
}

// but not here
person Rob    schedule 04.01.2015

Вы должны return (lat: lat, long: long).

person return true    schedule 04.01.2015
comment
Да, это решает проблему возврата правильных переменных. Но есть более глубокая проблема: он пытается немедленно вернуть данные, которые будут получены только асинхронно. Вместо этого OP должен использовать шаблон закрытия обработчика завершения. - person Rob; 05.01.2015
comment
@Rob Только что погуглил, чтобы проверить, и шаблон закрытия обработчика завершения не является стандартной терминологией ... Вы имеете в виду помещение оператора return в блок? - person Lyndsey Scott; 05.01.2015
comment
Нет, я не это имею в виду. Посмотрите на CLGeocoder метод geocodeAddressString. У него есть параметр completionHandler, который вызывается асинхронно (т. е. функция возвращается немедленно, но блок/замыкание с данными геокода вызывается позже, когда выполняется поиск адреса). вы должны использовать тот же шаблон в своем собственном коде. - person Rob; 05.01.2015