2017-02-07 2 views
0

Я хочу иметь class, который может получить название страны, используя CLGeocoder. Код ниже не работает, вероятно, потому что переменная country назначена self.country до того, как CLGeocoder закончит бег. Что я могу сделать? self.country действительно получает название страны от CLGeocoder?Использование CLGeocoder внутри класса init()

class Place { 

    let location: CLLocation 
    let country: String 

    init(location: CLLocation) { 

     self.location = location 

     var country = "" 

     CLGeocoder().reverseGeocodeLocation(location, completionHandler: { (placemarks, _) in 

      country = placemarks![0].country // I removed error and type checks for clarity  

     }) 

     self.country = country // self.country = "", but should be for example "Canada" 

    } 
} 

ответ

1

все, что вам нужно сделать, это переместить self.country = country внутри обработчика завершения. Данные возвращаются асинхронно, которые вы можете увидеть довольно хорошо, если вы установить точки останова на country = placeholder и self.country линий

Вы должны помнить, что при определении экземпляра Place в главном View Controller, значение place.country будет первоначально не определены. Вы можете проверить его снова после задержки, чтобы получить обновленную версию, или вы можете добавить делегата, так что он обновляет родительский контроллер, когда значение готов

вот простая версия

class Place { 

    let location: CLLocation 
    var country: String = "Undefined" 

    init(location: CLLocation) { 

     self.location = location 
     CLGeocoder().reverseGeocodeLocation(location, completionHandler: { (placemarks, _) in 
      self.country = placemarks![0].country! // I removed error and type checks for clarity  
     }) 
    } 
} 

и вот более элегантный вариант с делегатами

protocol CountryUpdatedDelegate 
{ 
    func countryUpdated(_ country : String) 
} 

class Place { 

    let location: CLLocation 
    var country: String = "Undefined" 

    var delegate : CountryUpdatedDelegate! 

    init(location: CLLocation) { 

     self.location = location 

     CLGeocoder().reverseGeocodeLocation(location, completionHandler: { (placemarks, _) in 
      guard let placeMarks = placemarks as [CLPlacemark]! else { 
       return 
      } 
      self.country = placemarks![0].country! // I removed error and type checks for clarity 
      self.delegate.countryUpdated(self.country) 
     }) 
    } 
} 

, а затем в вашем ViewController

class ViewController: UIViewController, CountryUpdatedDelegate { 

    let place = Place(location: location!) 
    place.delegate = self 





func countryUpdated(_ country : String) 
{ 
    print("Country has now been updated \(country)") 
} 
+0

Не работает ... Я получаю либо «Не могу присвоить свойство:« страна »- это« пусть »постоянная». или «self», захваченное закрытием до того, как все члены были инициализированы « – lukas

+0

, затем измените' let' на 'var' :-) – Russell

+0

изменение let to var дает вторую ошибку:« self »захвачен закрытием перед всеми членами были инициализированы « – lukas

Смежные вопросы