Reputation: 6484
This is my code
if loc.latitude != 0.0 && loc.longitude != 0.0 {
let loca = CLLocation(latitude: loc.latitude, longitude: loc.longitude)
geoCoder.reverseGeocodeLocation(loca) { (placemarks, error) in // this is the last line that is being called
var placemark : CLPlacemark!
placemark = placemarks?[0]
city = (placemark.addressDictionary?["City"] as! String)
}
}
Execution of this code snippet in my app goes right, no runtime errors occurred.
However, the last line that is being called is
geoCoder.reverseGeocodeLocation(loca){(placemarks, error)
I also double checked that loca
is not nil.
Why completion handler is not being called?
Upvotes: 2
Views: 6072
Reputation: 551
I came across this question and it seems as if there was some confusion regarding the answer. Here is the expansive way of getting location information using Swift 3, just for any future readers that come across this question.
This function code uses the didUpdateLocations
function and reverseGeocodeLocation()
to convert the location into a human readable address. It also sets the map view to the current user location. This of course is assuming you've set up your location manager object.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
// Get first location item returned from locations array
let userLocation = locations[0]
// Convert location into object with human readable address components
CLGeocoder().reverseGeocodeLocation(userLocation) { (placemarks, error) in
// Check for errors
if error != nil {
print(error ?? "Unknown Error")
} else {
// Get the first placemark from the placemarks array.
// This is your address object
if let placemark = placemarks?[0] {
// Create an empty string for street address
var streetAddress = ""
// Check that values aren't nil, then add them to empty string
// "subThoroughfare" is building number, "thoroughfare" is street
if placemark.subThoroughfare != nil && placemark.thoroughfare != nil {
streetAddress = placemark.subThoroughfare! + " " + placemark.thoroughfare!
} else {
print("Unable to find street address")
}
// Same as above, but for city
var city = ""
// locality gives you the city name
if placemark.locality != nil {
city = placemark.locality!
} else {
print("Unable to find city")
}
// Do the same for state
var state = ""
// administrativeArea gives you the state
if placemark.administrativeArea != nil {
state = placemark.administrativeArea!
} else {
print("Unable to find state")
}
// And finally the postal code (zip code)
var zip = ""
if placemark.postalCode != nil {
zip = placemark.postalCode!
} else {
print("Unable to find zip")
}
print("\(streetAddress)\n\(city), \(state) \(zip)")
}
}
}
// Create a coordinate based on users location latitude and longitude
let coordinate = CLLocationCoordinate2D(latitude: userLocation.coordinate.latitude,
longitude: userLocation.coordinate.longitude)
// Set the span (zoom) of the map view. Smaller number zooms in closer
let span = MKCoordinateSpan(latitudeDelta: 0.001, longitudeDelta: 0.001)
// Set the region, using your coordinates & span objects
let region = MKCoordinateRegion(center: coordinate, span: span)
// Set your map object's region to the region you just defined
map.setRegion(region, animated: true)
}
Upvotes: 0
Reputation: 23053
Use completionHandler
in Closure.
Check below example:
geoCoder.reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in
// Place details
var placeMark: CLPlacemark!
placeMark = placemarks?[0]
// Address dictionary
print(placeMark.addressDictionary, terminator: "")
// Location name
if let locationName = placeMark.addressDictionary!["Name"] as? NSString {
print(locationName, terminator: "")
}
// Street address
if let street = placeMark.addressDictionary!["Thoroughfare"] as? NSString {
print(street, terminator: "")
}
// City
if let city = placeMark.addressDictionary!["City"] as? NSString {
print(city, terminator: "")
}
// Zip code
if let zip = placeMark.addressDictionary!["ZIP"] as? NSString {
print(zip, terminator: "")
}
// Country
if let country = placeMark.addressDictionary!["Country"] as? NSString {
print(country, terminator: "")
}
})
Upvotes: 5