Does locationManager(_:didChangeAuthorization:) get called whenever an app first runs, even if neither location manager method requestWhenInUseAuthorization() or startUpdatingLocation() has been called? I'm trying to report location at the click of a button which I call in the @IBAction below:
@IBAction func findOutPressed(_ sender: UIButton) {
getLocation()
}
My CoreLocation code is in the extension below:
extension ViewController: CLLocationManagerDelegate {
// Called from findOutPressed to get location when button is clicked
func getLocation() {
let status = CLLocationManager.authorizationStatus()
handleLocationAuthorizationStatus(status: status)
}
// Respond to the result of the location manager authorization status
func handleLocationAuthorizationStatus(status: CLAuthorizationStatus) {
switch status {
case .notDetermined:
locationManager.requestWhenInUseAuthorization()
case .authorizedWhenInUse, .authorizedAlways:
locationManager.startUpdatingLocation()
case .denied:
print("I'm sorry - I can't show location. User has not authorized it")
case .restricted:
print("Access denied - likely parental controls are restricting use in this app.")
}
}
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
handleLocationAuthorizationStatus(status: status)
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let currentLocation = locations.last
let labelText = "My location is: latitude = \((currentLocation?.coordinate.latitude)!), longitude = \((currentLocation?.coordinate.longitude)!)"
resultLabel.text = labelText
locationManager.stopUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print("Dang, there was an error! Error: \(error)")
}
}
I'm finding locationManager(didChangeAuthorization:) is executing right away, even if the @IBAction findOutPressed hasn't been triggered with a click, and the results are being updated in my initially-blank resultsLabel before the user has clicked the button. I know I can set a flag to determine if the button was clicked or not, preventing the label from updating pre-maturely, but I'm trying to understand when locationManager(_:didChangeAuthorization) is triggered. Apple says: "This method is called whenever the application’s ability to use location services changes. Changes can occur because the user allowed or denied the use of location services for your application or for the system as a whole." It doesn't seem this covers the case of triggering when an app first runs. I'm grateful for anyone who can set me straight in my understanding of what's happening with authorization changes. Apologies if I've missed something basic. Thanks!
didChangeAuthorization
is called when the CLLocationManager is created, so even this will trigger:
var locationManager = CLLocationManager()
// ...
locationManager?.delegate = self
// ...
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
print( "authorization checked..." )
}
So you probably are setting & initializing your locationManager at the top of AppDelegate? That would trigger it. Then what happens is that the didChangeAuthorization starts updating location which then winds up calling your didUpudateLocation before the button was actually tapped.
Maybe declare locationManager as an optional and only init in findOutPressed() e.g.:
// class var:
var locationManager:CLLocationManager?location managers,
// ...
@IBAction func findOutPressed(_ sender: UIButton) {
locationManager = CLLocationManager()
locationManager?.delegate = self
getLocation()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With