Gestire la localizzazione GPS da iOS 8 in poi

Se avete sviluppato App per iOS che richiedono l’uso della localizzazione prima di iOS 8, cioè oggetti di tipo CLLocationManager, vi siete trovati con un grattacapo: la localizzazione sui dispositivi aggiornati non funziona più. Vediamo il perché e come deve cambiare il nostro codice per risolvere il problema.

Da iOS8 in avanti, le App devono infatti richiedere un permesso “al volo” attraverso l’apertura di un popup che informa l’utente sul tipo di permesso richiesto e sul motivo per cui lo chiede. Una politica analoga è stata adottata anche da Android che – dalla versione 6.0 in avanti – deve richiedere esplicitamente l’autorizzazione all’uso GPS.

Entrando nel dettaglio, innanzitutto nel file Info.plist relativo all’App, occorre aggiungere una delle due chiavi seguenti (o entrambe):

  • NSLocationAlwaysUsageDescription : per le applicazioni che richiedono la localizzazione in foreground, cioè a schermo attivo.
  • NSLocationWhenInUseUsageDescription : per le applicazioni che richiedono la localizzazione in background, cioè a schermo spento / dispositivo in standby.

Il testo che dovete aggiungere per queste chiavi è una stringa che spieghi all’utente il perché gli state chiedendo tale autorizzazione, cioè perché la vostra App ha bisogno della localizzazione, ad esempio: “L’applicazione necessita il GPS per trovare i servizi X vicini a te” oppure più genericamente “L’applicazione necessita il GPS per funzionare”.

Vediamo ora la parte di codice che deve essere aggiunta nel punto in cui avete allocato l’oggetto CLLocationManager (di norma, si trova nel metodo viewDidLoad. Avremo innanzitutto allocato un oggetto di tipo CLLocationManager in un modo similare a questo:
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;

Questa parte di codice non cambia da iOS7 a iOS8, ciò che cambia è che in iOS7 potevamo passare direttamente a richiedere la posizione con:
[locationManager startUpdatingLocation];
mentre da iOS8 in avanti dobbiamo richiedere l’autorizzazione:
if ([locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[self->locationManager requestWhenInUseAuthorization];
}

Anche in questo caso dobbiamo distinguere tra le due modalità di funzionamento viste in precedenza, cioè foreground e background, quindi utilizzeremo uno o entrambi i metodi:

  • requestWhenInUseAuthorization
  • requestAlwaysAuthorization

che hanno i significati già visti in precedenza.

Dobbiamo anche verificare che il dispositivo in uso abbia una versione di sistema operativo superiore o uguale alla 8 perché diversamente l’applicazione andrebbe in crash: non ho avuto modo di testare se effettivamente avviene un crash ma visto che è un test che viene effettuato solo una volta al lancio dell’applicazione, aggiungerlo non appesantirà l’esecuzione. Mettendo tutto insieme, il codice risultante sarà il seguente:

if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0 && [locationManager respondsToSelector:@selector(requestWhenInUseAuthorization)]) {
[self->locationManager requestWhenInUseAuthorization];
}

Ora tutto funzionerà. Ovviamente, il codice sarà analogo nel caso di requestAlwaysAuthorization.

Nelle parti successive del vostro codice, probabilmente sarà necessario verificare se l’utente ha fornito l’autorizzazione necessaria e se il GPS è attivo, in modo da decidere se l’applicazione può continuare ugualmente a lavorare con coordinate fittizie, oppure escludendo le funzionalità derivanti dal GPS, o se deve arrestarsi, ma questa logica farà parte della vostra implementazione.

Sperando che questo articolo sia stato utile, probabilmente in futuro vedremo le stesse cose riferite alla versione Android.

Lascia un commento