web-dev-qa-db-fra.com

gérer instantanément les autorisations de localisation dans swift

J'essaie d'implémenter une vue de base de la carte et d'ajouter la position actuelle d'un utilisateur à la carte sous forme d'annotation. J'ai ajouté la clé requestwheninuse à mon info.plist et importé coreLocation.

Dans ma vue, la méthode de chargement du contrôleur, j'ai les éléments suivants:

locManager.requestWhenInUseAuthorization()
var currentLocation : CLLocation

if(CLLocationManager.authorizationStatus() == CLAuthorizationStatus.AuthorizedWhenInUse){

    currentLocation = locManager.location
    println("currentLocation is \(currentLocation)")      
}
else{
    println("not getting location")
    // a default pin
}

Je reçois l'invite re. l'autorisation de récupérer l'emplacement. Pendant que cela se produit, je reçois mon impression disant de ne pas obtenir l'emplacement, évidemment parce que cela s'exécute avant que l'utilisateur n'ait la possibilité de cliquer sur OK. Si j'échappe à l'application et que je reviens, je peux récupérer l'emplacement et l'ajouter à la carte. Cependant, je veux que lorsque l'utilisateur appuie sur OK la première fois pour pouvoir ensuite saisir l'emplacement actuel et l'ajouter à la carte là-bas. Comment puis-je atteindre cet objectif? J'ai la méthode suivante pour ajouter une broche:

func addPin(location2D: CLLocationCoordinate2D){
    self.mapView.delegate = self
    var newPoint = MKPointAnnotation()
    newPoint.coordinate = location2D
    self.mapView.addAnnotation(newPoint)
}
16
user2363025

Pour ce faire, vous devez implémenter la méthode didChangeAuthorizationStatus pour votre délégué de gestionnaire d'emplacement qui est appelée peu de temps après l'initialisation de CLLocationManager.

Tout d'abord, en haut du fichier, n'oubliez pas d'ajouter: import CoreLocation

Pour ce faire, dans votre classe où vous utilisez l'emplacement, ajoutez le protocole délégué. Ensuite, dans la méthode viewDidLoad (ou applicationDidFinishLaunching si vous êtes dans le AppDelegate) initialisez votre gestionnaire d'emplacement et définissez sa propriété delegate sur self:

class myCoolClass: CLLocationManagerDelegate {
    var locManager: CLLocationManager!

    override func viewDidLoad() {
        locManager = CLLocationManager()
        locManager.delegate = self
    }
 }

Enfin, implémentez la méthode locationManager (_ didChangeAuthorizationStatus _) dans le corps de votre classe que vous avez déclaré précédemment, cette méthode sera appelée lorsque l'état de l'autorisation est modifié, donc dès que votre utilisateur clique sur le bouton. Vous pouvez l'implémenter comme ceci:

private func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
    switch status {
    case .notDetermined:
        // If status has not yet been determied, ask for authorization
        manager.requestWhenInUseAuthorization()
        break
    case .authorizedWhenInUse:
        // If authorized when in use
        manager.startUpdatingLocation()
        break
    case .authorizedAlways:
        // If always authorized
        manager.startUpdatingLocation()
        break
    case .restricted:
        // If restricted by e.g. parental controls. User can't enable Location Services
        break
    case .denied:
        // If user denied your app access to Location Services, but can grant access from Settings.app
        break
    default:
        break
    }
}

Swift 4 - Nouvelle syntaxe d'énumération

Pour Swift 4, il suffit de basculer la première lettre de chaque cas d'énumération en minuscules (.notDeterminé, .authorizedWhenInUse, .authorizedAlways, .restricted et .denied)

De cette façon, vous pouvez gérer chaque cas, que l'utilisateur donne son autorisation ou la révoque.

38
The Tom