Guida introduttiva a Places SDK per iOS (Objective-C)

1. Prima di iniziare

Prima di iniziare a scrivere il codice, devi configurare alcuni prerequisiti.

Xcode

Questo tutorial utilizza lo strumento Xcode di Apple, insieme al linguaggio Objective-C, per creare una semplice applicazione iOS che viene eseguita in un emulatore. Non è necessario un dispositivo fisico. Puoi scaricare Xcode all'indirizzo https://developer.apple.com/xcode/

CocoaPods

L'SDK Places per iOS è disponibile come pod CocoaPods. CocoaPods è uno strumento di gestione delle dipendenze open source per i progetti Swift e Objective-C. Se non hai già questo strumento, dovrai installarlo prima di procedere. Può essere installato dal terminale nel seguente modo:

sudo gem install cocoapods

Per maggiori dettagli su CocoaPods, consulta la guida introduttiva a CocoaPods.

Installazione dell'SDK

Per installare l'SDK, devi creare un Podfile nella directory del progetto che CocoaPods utilizzerà per scaricare e configurare le dipendenze necessarie. Il modo più semplice per farlo è creare un nuovo progetto in Xcode, aggiungere un Podfile e installare i pod.

Apri Xcode e vedrai la schermata "Welcome to Xcode" (Benvenuto in Xcode). Qui, seleziona "Crea un nuovo progetto Xcode".

4f1ecee473937c7b.png

Nella schermata successiva ti verrà chiesto un modello per il nuovo progetto. Seleziona "Applicazione a visualizzazione singola" per iOS e premi "Avanti".

Quando ti viene chiesto il nome del prodotto, puoi scegliere quello che preferisci, ma assicurati di annotare l'identificatore bundle generato per te. Ti servirà in un secondo momento.

72fbf25cb2db22ad.png

Premi "Avanti" e il progetto verrà creato. Prendi nota della directory in cui viene creato. Chiudi Xcode e, utilizzando Terminale, vai a questa directory.

Utilizzando il terminale, inserisci questo comando:

pod init

Verrà creato un file denominato Podfile. Modificalo per aggiungere un pod per Google Maps in questo modo:

target '{YOUR APP NAME}' do
pod 'GoogleMaps'
end

Salvalo e chiudi Xcode. Assicurati di chiuderlo, perché nel passaggio successivo modificherai il progetto sottostante. Una volta terminata l'operazione, aprirai un altro file di progetto ed è piuttosto comune che uno sviluppatore si confonda su dove si trova tutto se non ha chiuso Xcode in precedenza. Ora, in un terminale, vai alla directory del progetto ed esegui "pod install" come segue:

789c5bc62817f68a.png

Al termine, i pod verranno installati e verrà creato un nuovo file .xcworkspace. Utilizzalo per il progetto d'ora in poi. Prima di iniziare a programmare, però, avrai bisogno di una chiave API.

2. Recuperare la chiave API

Per il seguente passaggio di attivazione, abilita Maps SDK for iOS.

Configurare Google Maps Platform

Se non hai ancora un account Google Cloud Platform e un progetto con la fatturazione abilitata, consulta la guida Guida introduttiva a Google Maps Platform per creare un account di fatturazione e un progetto.

  1. Nella console Cloud, fai clic sul menu a discesa del progetto e seleziona il progetto che vuoi utilizzare per questo codelab.

  1. Abilita le API e gli SDK di Google Maps Platform richiesti per questo codelab in Google Cloud Marketplace. Per farlo, segui i passaggi descritti in questo video o in questa documentazione.
  2. Genera una chiave API nella pagina Credenziali di Cloud Console. Puoi seguire i passaggi descritti in questo video o in questa documentazione. Tutte le richieste a Google Maps Platform richiedono una chiave API.

3. Creazione dell'app API Places

Ora che hai creato un progetto della console e attivato l'API Places, ottenendo una chiave API, puoi iniziare a programmare la tua prima app API Places.

In precedenza, quando hai installato i file pod, è stato creato un nuovo file .xcworkspace. Apri il file facendo doppio clic.

19d62f34c08e645c.png

In Project Explorer noterai che ora è presente una nuova cartella chiamata "Pods". Se l'operazione è andata a buon fine, vedrai una cartella GoogleMaps contenente i framework.

8844d861f64c61aa.png

4. Modifica il file Info.plist.

La prima volta che esegui l'applicazione, iOS ti mostrerà una finestra di dialogo che chiede all'utente di concedere l'autorizzazione per accedere ai servizi di localizzazione. Questa finestra di dialogo fornisce una stringa che definisci e che inserisci nel file Info.plist. Se questa stringa non è presente, la finestra di dialogo non verrà visualizzata e la tua app non funzionerà.

Puoi trovare il file Info.plist in Esplora progetti qui:

c224c920ab3f1ef.png

Selezionalo e vedrai l'editor di plist.

859ca56f3b19da5.png

Passa il mouse sopra uno degli elementi e vedrai apparire un'icona "+". Premilo e vedrai una nuova voce. Inserisci il valore "NSLocationAlwaysUsageDescription" in questa casella.

9fb225d6f5508794.png

Premi Invio per aggiungere la nuova chiave. Poi fai doppio clic sulla colonna Valore per questa chiave e aggiungi una stringa:

5aefeb184187aa58.png

Per saperne di più su questa stringa, consulta la documentazione per gli sviluppatori Apple qui.

5. Modificare il delegato dell'app

In Esplora progetti, trova e apri AppDelegate.m. Lo utilizzerai per aggiungere la chiave API.

All'inizio del file, aggiungi questa riga immediatamente sotto la riga #import:

@import GoogleMaps;

Quindi, nella funzione didFinishLaunchingWithOptions:, aggiungi quanto segue appena prima della riga "return YES":

[GMSServices provideAPIKey:@"<Add your API Key>"];

Assicurati di utilizzare la chiave API che hai generato in precedenza.

6. Modificare il file dello storyboard

In Esplora progetti, apri il file Main.storyboard. Assicurati che la barra laterale sia attiva premendo il pulsante della barra laterale nell'angolo in alto a destra.

352af28b970d9e2.png

Quindi, nella parte inferiore della barra laterale, trova il controllo Etichetta assicurandoti che la libreria degli oggetti sia selezionata.

adec7051ae949531.png

Nella scena del controller di visualizzazione a sinistra, assicurati che sia selezionata l'opzione "Visualizza":

e4827b92b5861e3e.png

Quindi, trascina e rilascia 7 etichette nella visualizzazione. Disponili come mostrato qui. Assicurati di trascinare le dimensioni in modo che corrispondano a quelle mostrate. Puoi modificare il testo nell'etichetta facendo doppio clic e digitando il valore richiesto:

f8a9457772358069.png

Per l'etichetta più in basso (quella molto grande), vai all'editor delle proprietà e assicurati che sia impostata su 0 righe (il valore predefinito è 1). In questo modo, potrà eseguire il rendering di più righe.

a4abacf00d8888fe.png

7. Crea sbocchi per i valori

Per le tre etichette "valore", devi creare un punto vendita. In questo modo potrai modificarne i valori utilizzando il codice. Per farlo, devi prima attivare l'editor dell'assistente. Per farlo, chiudi prima la barra laterale delle proprietà facendo clic sul relativo pulsante per rimuoverla. (Questo pulsante è stato mostrato nel passaggio precedente)

Quindi, seleziona il pulsante dell'assistente, quello con il doppio cerchio mostrato qui:

e92dcc4ceea20a51.png

Assicurati che venga eseguito il rendering del file ViewController.h. In caso contrario, puoi modificarlo utilizzando l'editor nella parte superiore della finestra dell'assistente:

d42f0fcc18b84703.png

Quindi, tenendo premuto il tasto CONTROL, trascina ogni etichetta e rilasciala sotto la riga @interface nel file ViewController.h nell'assistente. Verrà visualizzata una finestra di dialogo che ti chiederà il tipo di connessione che vuoi stabilire:

a44b7888ed0f62b.png

Assicurati che le impostazioni siano quelle mostrate (Connessione: Outlet; Tipo: UILabel; Archiviazione: Weak), quindi assegna un nome a ciascuna. Ai fini di questo codelab, ho chiamato le etichette Longitudine, Latitudine e Altitudine rispettivamente lblLongitude, lblLatitude e lblAltidude. Trascina anche l'etichetta grande dalla parte inferiore e chiamala lblPlaces.

Al termine, il file ViewController.h dovrebbe avere il seguente aspetto:

#import <UIKit/UIKit.h>
@import GoogleMaps;

@interface ViewController : UIViewController
@property (weak, nonatomic) IBOutlet UILabel *lblLatitude;
@property (weak, nonatomic) IBOutlet UILabel *lblLongitude;
@property (weak, nonatomic) IBOutlet UILabel *lblAltitude;
@property (weak, nonatomic) IBOutlet UILabel *lblPlaces;

@end

8. Modificare il file di intestazione per le API Google Client e Location

Prima dei passaggi finali, in cui crei l'app per utilizzare l'API Places, devi configurare altre variabili nel file di intestazione (ViewController.h). Di seguito sono riportati il Core Location Manager e un oggetto Core Location:

@property (strong, nonatomic) CLLocationManager *locationManager;
@property (strong, nonatomic) CLLocation *location;

Avrai bisogno anche di un client API di Google:

@property GMSPlacesClient *placesClient;

Infine, devi aggiornare il file di intestazione in modo che la classe implementi CLLocationManagerDelegate:

@interface ViewController : UIViewController<CLLocationManagerDelegate>

Al termine, il file di intestazione dovrebbe avere il seguente aspetto:

#import <UIKit/UIKit.h>
#import <CoreLocation/CoreLocation.h>
#import <GoogleMaps/GoogleMaps.h>


@interface ViewController : UIViewController<CLLocationManagerDelegate>
@property (strong, nonatomic) CLLocationManager *locationManager;
@property (strong, nonatomic) CLLocation *location;
@property (weak, nonatomic) IBOutlet UILabel *lblLongitude;
@property (weak, nonatomic) IBOutlet UILabel *lblLatitude;
@property (weak, nonatomic) IBOutlet UILabel *lblAltitude;
@property (weak, nonatomic) IBOutlet UILabel *lblPlaces;

@property GMSPlacesClient *placesClient;
@end

9. Modificare il controller di visualizzazione

Il primo passaggio consiste nel modificare la funzione viewDidLoad per inizializzare il Location Manager, richiedere l'autorizzazione dell'utente per accedere alla posizione e infine avviare il Location Manager in modo che monitori la posizione attuale. Inizializzerai anche il client dell'API Google Places.

- (void)viewDidLoad {
    [super viewDidLoad];
    self.locationManager = [[CLLocationManager alloc]init];
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    if([self.locationManager respondsToSelector:@selector(requestAlwaysAuthorization)]) {
        [self.locationManager requestAlwaysAuthorization];
        // Or [self.locationManager requestWhenInUseAuthorization];
    }
    [self.locationManager startUpdatingLocation];
    
    self.locationManager.delegate = self;
    self.location = [[CLLocation alloc] init];
    self.placesClient = [GMSPlacesClient sharedClient];
}

10. Gestire gli aggiornamenti della posizione

Il gestore della posizione richiamerà il tuo controller di visualizzazione con gli aggiornamenti della posizione chiamando la funzione didUpdateLocations. Devi aggiungere questo codice a ViewController.m. La funzione è simile a questa:

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
    // Enter code here
}

Questa funzione dovrà svolgere diverse operazioni.

Innanzitutto, memorizzerà nella cache la posizione con l'ultima ricevuta:

self.location = locations.lastObject;

Successivamente, devono essere aggiornate le tre etichette per latitudine, longitudine e altitudine:

self.lblLatitude.text = [NSString stringWithFormat:@"%f", self.location.coordinate.latitude];

self.lblLongitude.text = [NSString stringWithFormat:@"%f", self.location.coordinate.longitude];

self.lblAltitude.text = [NSString stringWithFormat:@"%f", self.location.altitude];

Successivamente chiamerai l'API Places utilizzando il client Places. A questo scopo, specifica la funzione di callback, che riceverà l'elenco delle probabilità dei luoghi. L'API Places determina la probabilità che tu ti trovi in un determinato luogo in base alla tua posizione. Restituisce il nome dei luoghi probabili, insieme a un valore compreso tra 0 e 1 contenente la probabilità che ti trovi in quel luogo.

[self.placesClient currentPlaceWithCallback:^(GMSPlaceLikelihoodList *likelihoodList, NSError *error) {

A questo punto, puoi implementare il callback. Verrà eseguita l'iterazione nell'elenco delle probabilità, aggiungendo luoghi e probabilità per questi luoghi.

[self.placesClient currentPlaceWithCallback:^(GMSPlaceLikelihoodList *likelihoodList, NSError *error) {

  if (error != nil) {
    NSLog(@"Current Place error %@", [error localizedDescription]);
    return;
  }
  NSMutableString *strPlaces = [NSMutableString stringWithString:@""];

  for (GMSPlaceLikelihood *likelihood in likelihoodList.likelihoods) {
    GMSPlace* place = likelihood.place;
    NSLog(@"Current Place name %@ at likelihood %g", place.name,
            likelihood.likelihood);
    NSLog(@"Current Place address %@", place.formattedAddress);
    NSLog(@"Current Place attributions %@", place.attributions);
    NSLog(@"Current PlaceID %@", place.placeID);
    [strPlaces appendString:place.name];
    [strPlaces appendString:@" "];
    [strPlaces appendFormat:@"%g",likelihood.likelihood];
    [strPlaces appendString:@"\n"];
  }
  self.lblPlaces.text = strPlaces;
}];

Al termine, la funzione didUpdateLocations dovrebbe avere il seguente aspetto:

-(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
    
    self.location = locations.lastObject;
    self.lblLatitude.text = [NSString stringWithFormat:@"%f", self.location.coordinate.latitude];
    self.lblLongitude.text = [NSString stringWithFormat:@"%f", self.location.coordinate.longitude];
    self.lblAltitude.text = [NSString stringWithFormat:@"%f", self.location.altitude];
    
    NSLog(@"%@", self.location.description);
    
    [self.placesClient currentPlaceWithCallback:^(GMSPlaceLikelihoodList *likelihoodList, NSError *error) {

        if (error != nil) {
            NSLog(@"Current Place error %@", [error localizedDescription]);
            return;
        }
        NSMutableString *strPlaces = [NSMutableString stringWithString:@""];
        
        for (GMSPlaceLikelihood *likelihood in likelihoodList.likelihoods)  
        {
            GMSPlace* place = likelihood.place;
            NSLog(@"Current Place name %@ at likelihood %g", place.name, likelihood.likelihood);
            NSLog(@"Current Place address %@", place.formattedAddress);
            NSLog(@"Current Place attributions %@", place.attributions);
            NSLog(@"Current PlaceID %@", place.placeID);
            [strPlaces appendString:place.name];
            [strPlaces appendString:@" "];
            [strPlaces appendFormat:@"%g",likelihood.likelihood];
            [strPlaces appendString:@"\n"];
        }
        self.lblPlaces.text = strPlaces;
    }];
}

Ora puoi eseguire l'app e testarla.

11. Esecuzione dell'app nell'emulatore

Esegui l'app utilizzando il pulsante Esegui nella barra del titolo. In questo modo puoi anche selezionare il tipo di esecuzione e, come puoi vedere qui, sto eseguendo il test su un iPhone 6 utilizzando l'emulatore.

bbbe0b8820c8a913.png

Quando premi il pulsante di esecuzione, l'app viene creata e avviata. Vedrai la richiesta di autorizzazione per l'accesso alla posizione, inclusa la stringa personalizzata che hai specificato in precedenza.

b9bb2ace7e68f186.png

Una volta fatto, vedrai l'aggiornamento di latitudine e longitudine. Per modificare la posizione, seleziona il menu Debug e scegli una posizione. Ad esempio, puoi scegliere "Freeway Drive".

dcb1ce091d780f56.png

In questo modo, vedrai la posizione con i luoghi probabili che si aggiornano, simulando il viaggio in autostrada.

649e3eeb2321ae03.png

È tutto. Hai eseguito l'accesso correttamente ai dettagli del luogo corrente utilizzando l'API Google Places su iOS.