2014-12-01 11 views
11

Quando si aggiunge un componente MKMapView alla vista in Interface Builder, ci sono caselle di controllo che consentono di configurare quello che mostra:Come utilizzare "Mostra la posizione dell'utente" di MKMapView in iOS8?

enter image description here

Quando si seleziona "User Location", mostra automaticamente posizione dell'utente sul carta geografica.

Tuttavia, poiché iOS 8 dovresti chiedere il permesso di posizione prima di mostrare la posizione dell'utente. In caso contrario, viene visualizzato il messaggio "Tentativo di avviare gli aggiornamenti della posizione di MapKit senza chiedere conferma" nella console.

Così Ho una chiave NSLocationWhenInUseUsageDescription al plist, e ha aggiunto questo codice di viewDidLoad:

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

Questo non sembra funzionare, però. Ricevo un popup che chiede il permesso, ma prima di selezionare una risposta, si nasconde da sola, la mappa viene caricata sotto di essa e ricevo l'avviso nella console.

So che posso impostare la proprietà showsUserLocation nel codice, solo dopo aver ottenuto l'autorizzazione; ma il mio punto è, c'è questa casella di controllo in IB che dovrebbe fare la stessa cosa, tranne che avvia immediatamente il monitoraggio. Significa che non dovremmo usare questa casella di controllo a partire da iOS 8? O lo sto usando in modo errato?

-

Update: in realtà, le pelli popup di per sé, indipendentemente se "indica la posizione dell'utente" è impostato o meno. Ho provato a farlo in viewWillAppear o viewDidAppear invece, ma questo non ha aiutato. Quindi non so dove esattamente dovrei chiamare requestwhenInUseAuthorization quando si utilizza un MKMapView ...

risposta

9

L'istanza CLLocationManager viene rilasciata da ARC dopo il completamento dell'esecuzione del metodo. Non appena l'istanza è stata rilasciata, la finestra di dialogo è scomparsa. La soluzione era piuttosto semplice. Modificare l'istanza CLLocationManager dall'essere una variabile a livello di metodo per essere una variabile di istanza a livello di classe, e renderlo Strong - questo è per objC :)

Per Swift ... fare qualcosa di simile:

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() 
      } 
    ... 
    } 

così ... non utilizzare CLLocationManager().requestWhenInUseAuthorization() - invece utilizzare locationManager.requestWhenInUseAuthorization() - locationManager dichiarato all'inizio

+0

Ah, hai ragione, ARC mi fa dimenticare completamente la gestione della memoria e questo a volte porta a cose come questa. Sembra che ora non mostri nemmeno il pop-up se non mantengo il manager. Se lo faccio, funziona come dovrebbe, grazie. –

+0

Felice di aiutarti! :) – TonyMkenu

+0

Immagino che il riferimento al delegato non sia sufficiente per mantenere l'istanza in giro. Grazie ancora! – Quincy

0

requestWhenInUseAuthorization è asincrona - assicurarsi che si sta ascoltando modificare lo stato di autorizzazione nel tuo cartina delegato prima realmente cercando di rintracciare o mostrare la posizione dell'utente

+3

Ma qui è la cosa, non sto iniziando a tracciare la posizione dell'utente nel codice. Se controllo IB "Shows: User Location", allora il caricatore NIB lo fa, e lo avvia automaticamente e in modo asincrono con qualunque cosa stia facendo nel delegato/controller. Quindi, quello che sto chiedendo è, c'è un modo per farlo correttamente utilizzando questa casella di controllo in iOS 8? –