all you have to do is move self.country = country
inside the completion handler. The data is returned asynchronously, which you can see quite nicely if you set breakpoints on the country = placeholder
and self.country
lines
You will need to remember that when you define an instance of Place
in your main View Controller, the value of place.country
will not initially be defined. You can either check it again after a delay to get the updated version, or you can add a delegate so that it updates the parent controller when the value is ready
here's the simple version
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
})
}
}
and here's the more elegant version with delegates
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)
})
}
}
and then in your ViewController
class ViewController: UIViewController, CountryUpdatedDelegate {
let place = Place(location: location!)
place.delegate = self
func countryUpdated(_ country : String)
{
print("Country has now been updated \(country)")
}