I have a locationManager function to grab the users current location and posting the name of the city and state. I have a print statement so I can check in my console if everything is working properly...and it is. However, it prints the city location 3 times. This actually causes an issue in my actual app but thats beyond the point of this question.
My function is as follows:
var usersLocation: String!
var locationManager: CLLocationManager!
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation: CLLocation = locations[0]
CLGeocoder().reverseGeocodeLocation(userLocation) { (placemarks, error) -> Void in
if error != nil {
print(error)
} else {
let p = placemarks?.first // ".first" returns the first element in the collection, or nil if its empty
// this code above will equal the first element in the placemarks array
let city = p?.locality != nil ? p?.locality : ""
let state = p?.administrativeArea != nil ? p?.administrativeArea : ""
self.navigationBar.title = ("\(city!), \(state!)")
self.usersLocation = ("\(city!), \(state!)")
self.locationManager.stopUpdatingLocation()
print(self.usersLocation)
self.refreshPosts()
}
}
}
So in my print(self.usersLocation) it will print in my console three times. Is this normal?
UPDATE TO SHOW VIEWDIDLOAD
override func viewDidLoad() {
super.viewDidLoad()
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
self.tableView.rowHeight = UITableViewAutomaticDimension
self.tableView.estimatedRowHeight = 250.0
}
I'd first suggest a few things:
Call
stopUpdatingLocation
before you performreverseGeocodeLocation
.You are calling
stopUpdatingLocation
inside thereverseGeocodeLocation
completion handler closure. The problem is that this runs asynchronously, and thusdidUpdateLocations
may receive additional location updates in the intervening period. And often, when you first start location services, you'll get a number of updates, often with increasing accuracy (e.g.horizontalAccuracy
values that are smaller and smaller). If you turn off location services before initiating asynchronous geocode request, you'll minimize this issue.You can also add add a
distanceFilter
inviewDidLoad
, which will minimize redundant calls to the delegate method:You can use your own state variable that checks to see if the reverse geocode process has been initiated. For example: