Como começar a usar o SDK do Places para iOS (Objective-C)

1. Antes de começar

Antes de começar a programar, há alguns pré-requisitos que você precisa configurar.

Xcode

Este tutorial usa a ferramenta Xcode da Apple e a linguagem Objective-C para criar um aplicativo iOS simples que é executado em um emulador. Você não precisa de um dispositivo físico. Você pode acessar o Xcode em https://developer.apple.com/xcode/

CocoaPods

O SDK do Places para iOS está disponível como um pod do CocoaPods. O CocoaPods é uma ferramenta de gerenciamento de dependências de código aberto para projetos em Swift e Objective-C. Se você ainda não tiver essa ferramenta, instale-a antes de continuar. Ele pode ser instalado no terminal assim:

sudo gem install cocoapods

Para mais detalhes sobre o CocoaPods, consulte o Guia de primeiros passos do CocoaPods (em inglês).

Como instalar o SDK

Para instalar o SDK, crie um Podfile no diretório do projeto que o CocoaPods vai usar para fazer o download e configurar as dependências necessárias. A maneira mais fácil de fazer isso é criar um projeto no Xcode, adicionar um Podfile e instalar os pods nele.

Abra o Xcode. A tela "Bem-vindo ao Xcode" vai aparecer. Selecione "Criar um projeto do Xcode".

4f1ecee473937c7b.png

Na próxima tela, você vai precisar escolher um modelo para o novo projeto. Selecione "Single View Application" para iOS e pressione "Next".

Quando for solicitado o nome do produto, escolha o que quiser, mas anote o identificador do pacote gerado para você. Você vai precisar dele mais tarde.

72fbf25cb2db22ad.png

Clique em "Próxima" para criar o projeto. Anote o diretório em que ele foi criado. Feche o Xcode e, usando o Terminal, navegue até esse diretório.

Usando o terminal, digite o seguinte comando:

pod init

Um arquivo chamado Podfile será criado para você. Edite-o para adicionar um pod para o GoogleMaps desta forma:

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

Salve e feche o Xcode. Feche-o, porque na próxima etapa você vai editar o projeto subjacente. Você vai abrir um arquivo de projeto diferente quando isso for concluído, e é muito comum um desenvolvedor se confundir sobre onde tudo está se não tiver fechado o Xcode antes. Agora, em um terminal, acesse o diretório do projeto e execute "pod install" desta forma:

789c5bc62817f68a.png

Quando terminar, os pods serão instalados e um novo arquivo .xcworkspace será criado. Use esse nome para o projeto de agora em diante. Mas, antes de programar, você vai precisar de uma chave de API.

2. Receber sua chave de API

Para a etapa a seguir, ative o SDK do Maps para iOS.

Configurar a Plataforma Google Maps

Caso você ainda não tenha uma conta do Google Cloud Platform e um projeto com faturamento ativado, veja como criá-los no guia da Plataforma Google Maps.

  1. No Console do Cloud, clique no menu suspenso do projeto e selecione o projeto que você quer usar neste codelab.

  1. Ative as APIs e os SDKs da Plataforma Google Maps necessários para este codelab no Google Cloud Marketplace. Para fazer isso, siga as etapas descritas neste vídeo ou nesta documentação.
  2. Gere uma chave de API na página Credenciais do Console do Cloud. Siga as etapas indicadas neste vídeo ou nesta documentação. Todas as solicitações à Plataforma Google Maps exigem uma chave de API.

3. Como criar o app da API Places

Agora que você criou um projeto do console e ativou a API Places nele, obtendo uma chave de API, já pode começar a programar seu primeiro app da API Places.

Antes, quando você instalou os arquivos do pod, um novo arquivo .xcworkspace foi criado para você. Clique duas vezes para abrir.

19d62f34c08e645c.png

No Project Explorer, você vai notar que agora há uma nova pasta chamada "Pods". Se isso funcionar, você vai encontrar uma pasta "GoogleMaps" com os frameworks.

8844d861f64c61aa.png

4. Edite o arquivo Info.plist.

Quando você executar o aplicativo pela primeira vez, o iOS vai mostrar uma caixa de diálogo pedindo que o usuário conceda permissão para acessar os serviços de localização. Essa caixa de diálogo vai fornecer uma string que você define e coloca no arquivo Info.plist. Se essa string não estiver presente, a caixa de diálogo não vai aparecer, e o app não vai funcionar.

Você pode encontrar o arquivo Info.plist no explorador de projetos aqui:

c224c920ab3f1ef.png

Selecione-o para abrir o editor de plist.

859ca56f3b19da5.png

Passe o cursor sobre qualquer um dos elementos para ver um ícone de "+". Pressione-o para ver uma nova entrada. Insira o valor "NSLocationAlwaysUsageDescription" nessa caixa.

9fb225d6f5508794.png

Pressione "Enter" para adicionar a nova chave. Em seguida, clique duas vezes na coluna "Valor" dessa chave e adicione uma string:

5aefeb184187aa58.png

Para saber mais sobre essa string, consulte a documentação para desenvolvedores da Apple aqui.

5. Editar o delegado do app

No explorador de projetos, encontre e abra AppDelegate.m. Você vai usar esse arquivo para adicionar sua chave de API.

Na parte de cima do arquivo, adicione isso logo abaixo da linha #import:

@import GoogleMaps;

Em seguida, na função didFinishLaunchingWithOptions:, adicione o seguinte logo acima da linha "return YES":

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

Use a chave de API que você gerou anteriormente.

6. Editar o arquivo de storyboard

No explorador de projetos, abra o arquivo Main.storyboard. Confira se a barra lateral está ativa pressionando o botão dela no canto superior direito.

352af28b970d9e2.png

Em seguida, na parte de baixo da barra lateral, encontre o controle de rótulo. Para isso, verifique se a biblioteca de objetos está selecionada.

adec7051ae949531.png

Na cena do controlador de visualização à esquerda, verifique se a opção "Visualização" está selecionada:

e4827b92b5861e3e.png

Em seguida, arraste e solte sete rótulos na visualização. Organize-os como mostrado aqui. Arraste os tamanhos para corresponder ao que é mostrado. Para editar o texto no rótulo, clique duas vezes nele e digite o valor necessário:

f8a9457772358069.png

Para o rótulo mais abaixo (o muito grande), acesse o editor de propriedades e verifique se ele está definido para ter 0 linhas (o padrão é 1). Isso permite renderizar várias linhas.

a4abacf00d8888fe.png

7. Criar saídas para os valores

Para os três rótulos "value", você precisa criar um outlet. Isso permite mudar os valores usando código. Para fazer isso, primeiro ative o editor assistente. Para fazer isso, primeiro feche a barra lateral de propriedades clicando no botão dela para remover. (Esse botão foi mostrado na etapa anterior)

Em seguida, selecione o botão do Google Assistente, que é o círculo duplo mostrado aqui:

e92dcc4ceea20a51.png

Verifique se ele está renderizando o arquivo ViewController.h. Caso contrário, mude para fazer isso usando o editor na parte de cima da janela do assistente:

d42f0fcc18b84703.png

Em seguida, com a tecla CONTROL pressionada, arraste cada rótulo e solte abaixo da linha @interface no arquivo ViewController.h no assistente. Uma caixa de diálogo vai aparecer perguntando que tipo de conexão você quer fazer:

a44b7888ed0f62b.png

Verifique se as configurações estão como mostrado (Conexão: Outlet; Tipo: UILabel; Armazenamento: Weak) e dê um nome a cada uma. Para fins deste codelab, chamei os rótulos de longitude, latitude e altitude de lblLongitude, lblLatitude e lblAltitude, respectivamente. Arraste também o rótulo grande da parte de baixo e chame-o de lblPlaces.

Quando você terminar, o arquivo ViewController.h terá esta aparência:

#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. Editar o arquivo de cabeçalho para APIs de localização e do cliente do Google

Antes das etapas finais, em que você cria o app para usar a API Places, é necessário configurar mais algumas variáveis no arquivo de cabeçalho (ViewController.h). Estes são o gerenciador de localização principal e um objeto de localização principal:

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

Você também vai precisar de um cliente da API do Google:

@property GMSPlacesClient *placesClient;

Por fim, você precisará atualizar o arquivo de cabeçalho para que a classe implemente o CLLocationManagerDelegate:

@interface ViewController : UIViewController<CLLocationManagerDelegate>

Quando você terminar, o arquivo de cabeçalho vai ficar assim:

#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. Editar o controlador de visualização

A primeira etapa é editar a função viewDidLoad para inicializar o gerenciador de local, solicitar a autorização do usuário para acessar a localização e, por fim, iniciar o gerenciador de local para que ele rastreie a localização atual. Você também vai inicializar o cliente da 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. Processar atualizações de localização

O gerenciador de locais vai retornar ao controlador de visualização com atualizações de localização chamando a função didUpdateLocations. Adicione isso ao ViewController.m. A função tem esta aparência:

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

Essa função precisa fazer várias coisas.

Primeiro, ele vai armazenar em cache a localização com a última recebida:

self.location = locations.lastObject;

Em seguida, os três rótulos de latitude, longitude e altitude precisam ser atualizados:

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];

Em seguida, você vai chamar a API Places usando o cliente de lugares. Para isso, especifique a função de callback, que vai receber a lista de probabilidades de lugares. A API Places determina a probabilidade de você estar em um determinado lugar com base na sua localização. Ele retorna o nome de lugares prováveis, além de um valor entre 0 e 1 que contém a probabilidade de você estar lá.

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

Em seguida, implemente o callback. Isso vai fazer uma iteração na lista de probabilidades, adicionando lugares e probabilidades para esses lugares.

[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;
}];

Quando você terminar, a função "didUpdateLocations" vai ficar assim:

-(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;
    }];
}

Agora você já pode executar e testar o app.

11. Executar o app no emulador

Execute o app usando o botão de execução na barra de título. Isso também permite selecionar o tipo de execução. Como você pode ver aqui, estou testando em um iPhone 6 usando o emulador.

bbbe0b8820c8a913.png

Quando você pressionar o botão de execução, o app será criado e iniciado. Você vai ver a solicitação para permitir que o app acesse a localização, incluindo a string personalizada especificada anteriormente.

b9bb2ace7e68f186.png

Depois disso, você vai ver a atualização da latitude e da longitude. Para mudar o local, selecione o menu "Depurar" e escolha um local. Por exemplo, você pode escolher "Freeway Drive".

dcb1ce091d780f56.png

Ao fazer isso, você vai ver o local com os lugares prováveis sendo atualizados, simulando o percurso na rodovia.

649e3eeb2321ae03.png

Pronto. Você acessou os detalhes do lugar atual usando a API Google Places no iOS.