I am trying to set up a function to get my current location in app delegate but when I print(city)
at the bottom it returns the original initialized value in the global variable which is "hello", even though I updated the value under the CLGeocoder.
AppDelegate:
import UIKit
import CoreData
import CoreLocation
let appDelegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
var country = "hello"
var city = "hello"
func setupLocationManager(){
let locationManager = CLLocationManager()
locationManager.requestAlwaysAuthorization()
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.startUpdatingLocation()
}
// Below method will provide you current location.
func getLocation() -> [String]{
let manager = CLLocationManager()
manager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
manager.requestAlwaysAuthorization()
manager.startUpdatingLocation()
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestAlwaysAuthorization()
manager.startUpdatingLocation()
let selflocation = manager.location
let latitude: Double = selflocation!.coordinate.latitude
let longitude: Double = selflocation!.coordinate.longitude
print("current latitude :: \(latitude)")
print("current longitude :: \(longitude)")
let location = CLLocation(latitude: latitude, longitude: longitude) //changed!!!
CLGeocoder().reverseGeocodeLocation(location, completionHandler: {(placemarks, error) -> Void in
print(location)
if error != nil {
print("Reverse geocoder failed with error" + (error?.localizedDescription)!)
}
let pm = placemarks![0]
let speed = (selflocation?.speed)!
city = pm.addressDictionary!["City"]! as! String
country = pm.addressDictionary!["Country"]! as! String
if (placemarks?.count)! > 0 {
}
else {
print("Problem with the data received from geocoder")
}
})
print(city)
return [city as! String, country as! String]
}
This is because the geocoding is done asynchronously, so the print(city)
is being executed before the geocoding is completed. So I suggest you do this.
func getLocation(completion: @escaping (Array<String>)->()){
let manager = CLLocationManager()
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestAlwaysAuthorization()
manager.startUpdatingLocation()
let selflocation = manager.location
let latitude: Double = selflocation!.coordinate.latitude
let longitude: Double = selflocation!.coordinate.longitude
let location = CLLocation(latitude: latitude, longitude: longitude)
CLGeocoder().reverseGeocodeLocation(location, completionHandler: {(placemarks, error) -> Void in
if let error = error {
print(error.localizedDescription)
return
}
if let placemark = placemarks?.first {
if let country = placemark.country, let city = placemark.locality {
completion([city, country])
return
} else {
print("country or city was nil.")
}
} else {
print("Problem with the data received from geocoder")
}
})
}
So instead of calling getLocation()
call
getLocation { (location) in
print(location)
}