¿Cómo usar MKMapView "Muestra la location del usuario" en iOS8?

Cuando agrega un componente MKMapView a la vista en Interface Builder, hay casillas de verificación que le permiten configurar lo que muestra:

introduzca la descripción de la imagen aquí

Cuando marca "Ubicación del usuario", muestra automáticamente la location del usuario en el map.

Sin embargo, desde iOS 8 se debe pedir permiso de location antes de mostrar la location del usuario. Si no lo hace, recibirá una advertencia "Intentando iniciar las actualizaciones de location de MapKit sin preguntar" en la console.

Entonces agregué una key NSLocationWhenInUseUsageDescription al plist y agregué este código para viewDidLoad :

 if CLLocationManager.authorizationStatus() == .NotDetermined { CLLocationManager().requestWhenInUseAuthorization() } 

Sin embargo, esto no parece funcionar. Recibo una window emergente pidiéndome permiso, pero antes de seleccionar una respuesta, se oculta sola, el map se carga debajo y recibo la advertencia en la console.

Sé que puedo establecer la propiedad showsUserLocation en el código, solo después de get el permiso; pero mi punto es que hay una casilla en IB que debe hacer lo mismo, excepto que comienza el seguimiento de inmediato. ¿Eso significa que no se supone que debamos utilizar esta checkbox en absoluto desde iOS 8? ¿O estoy usando incorrectamente?

Actualización: en realidad, el popup se esconde por sí mismo independientemente de si "muestra la location del usuario" está configurado o no. He intentado hacerlo en viewWillAppear o viewDidAppear en viewDidAppear lugar, pero eso no ayudó. Así que no estoy seguro de dónde exactamente se supone que requestwhenInUseAuthorization llamar a requestwhenInUseAuthorization cuando uso un MKMapView

CLLocationManager instancia de CLLocationManager es liberada por ARC después de que el método terminó de ejecutarse. Tan pronto como se lanzó la instancia, el cuadro de dialog desapareció. La solución fue bastante simple. Cambie la instancia de CLLocationManager de ser una variable de nivel de método para que sea una variable de instancia de nivel de class, y hágala fuerte : esto es para ObjC 🙂

Para Swift … haz algo como eso:

  class YourViewController: UIViewController,CLLocationManagerDelegate { ... let locationManager = CLLocationManager() override func viewDidLoad() { super.viewDidLoad() // Ask for permission for location locationManager.delegate = self if(locationManager.respondsToSelector("requestAlwaysAuthorization")) { locationManager.requestAlwaysAuthorization() //or //locationManager.requestWhenInUseAuthorization() } ... } 

así que … no use CLLocationManager().requestWhenInUseAuthorization() – en su lugar use locationManager.requestWhenInUseAuthorization() – locationManager declarado tempranamente

requestWhenInUseAuthorization es asíncrono: asegúrese de que está escuchando el estado de cambio de autorización en su delegado de vista de map antes de tratar de rastrear o mostrar la location del usuario.