J'ai un contrôleur de vue qui implémente le CLLocationManagerDelegate
. Je crée une variable CLLocationManager:
let locationManager = CLLocationManager()
Puis dans le viewDidLoad
, je définis les propriétés:
// Set location manager properties
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationManager.distanceFilter = 50
Le problème vient que la fonction est appelée avant même que je vérifie l'état d'autorisation.
func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
if (status == .AuthorizedWhenInUse) {
// User has granted autorization to location, get location
locationManager.startUpdatingLocation()
}
}
Quelqu'un peut-il m'informer de ce qui pourrait provoquer ce problème?
- locationManager:didChangeAuthorizationStatus:
est appelé peu de temps après l'initialisation de CLLocationManager
.
Vous pouvez demander une autorisation à l'intérieur de la méthode déléguée si vous souhaitez:
func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
switch status {
case .NotDetermined:
locationManager.requestAlwaysAuthorization()
break
case .AuthorizedWhenInUse:
locationManager.startUpdatingLocation()
break
case .AuthorizedAlways:
locationManager.startUpdatingLocation()
break
case .Restricted:
// restricted by e.g. parental controls. User can't enable Location Services
break
case .Denied:
// user denied your app access to Location Services, but can grant access from Settings.app
break
default:
break
}
}
Sachez que vous devez affecter le délégué en temps opportun si vous voulez que cela fonctionne.
Si vous retardiez d'une manière ou d'une autre l'affectation du délégué, par ex. en le définissant de manière asynchrone, vous risquez de manquer l'appel initial à - locationManager:didChangeAuthorizationStatus:
.
Swift
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
switch status {
case .notDetermined:
manager.requestAlwaysAuthorization()
break
case .authorizedWhenInUse:
manager.startUpdatingLocation()
break
case .authorizedAlways:
manager.startUpdatingLocation()
break
case .restricted:
// restricted by e.g. parental controls. User can't enable Location Services
break
case .denied:
// user denied your app access to Location Services, but can grant access from Settings.app
break
}
}
Les autres réponses pourraient introduire de nouveaux comportements indésirables.
Vous pouvez simplement ajouter un booléen et un garde pour empêcher le premier appel, avec quelques commentaires expliquant le bogue:
var firstTimeCalled = true
// ...
func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
guard !firstTimeCalled else {
firstTimeCalled = false
return
}
// ... send status to listeners
}