1. Antes de começar
Este codelab ensina a criar um app iOS simples que usa o SDK Navigation da Plataforma Google Maps para navegar até um destino pré-configurado.
O app vai ter esta aparência quando você terminar.

Pré-requisitos
- Conhecimento básico de desenvolvimento de apps iOS em Swift.
- Alguma familiaridade com conceitos básicos do SDK do Google Maps, como criar um mapa centralizado em um local específico.
O que você vai aprender
- Como criar um app iOS Swift simples que usa o SDK Navigation para navegar até um destino.
- Como integrar o SDK Navigation do repositório remoto do Cocoapods.
- Como gerenciar permissões de localização e o contrato do usuário com os termos do usuário final do SDK Navigation.
- Como inicializar o SDK.
- Como definir um destino e iniciar o trajeto.
O que é necessário
- A versão estável mais recente do Xcode.
- Uma Conta do Google e um projeto com o faturamento ativado.
- Um dispositivo iOS ou um dispositivo emulado executado no Xcode Simulator. Qualquer uma das opções escolhidas precisa atender aos requisitos mínimos do SDK Navigation.
2. Começar a configuração
Se você ainda não tiver uma conta do Google Cloud Platform e um projeto na nuvem com faturamento ativado, siga as instruções em Primeiros passos com a Plataforma Google Maps para configurar seu projeto do Google Cloud.
Selecionar um projeto na nuvem do Google no console
No Console do Cloud, clique no menu suspenso do projeto e selecione o projeto que você quer usar neste codelab.

Ativar o SDK Navigation no seu projeto
Ative as APIs e os SDKs da Plataforma Google Maps necessários para este codelab no Google Cloud Marketplace.
Acesse APIs e serviços > Biblioteca no console do Google Cloud e pesquise "SDK Navigation".
Você vai ver um resultado da pesquisa.

Clique em SDK Navigation para abrir a página de detalhes do produto. Clique em Ativar para ativar o SDK no seu projeto.
Repita esse processo para o SDK do Google Maps para iOS.
crie uma chave de API
Gere uma chave de API na página Credenciais do Console do Cloud. Todas as solicitações à Plataforma Google Maps exigem uma chave de API. Na página "Credenciais" do console. Clique em "+ Criar credenciais" na parte de cima da página e selecione "Chave de API" nas opções.
Para uso em produção, a prática recomendada é definir uma restrição de aplicativo para sua chave de API, mas isso é opcional para este codelab.
3. Acessar os arquivos do projeto de exemplo
Nesta seção, descrevemos como configurar um projeto básico de app XCode vazio clonando arquivos do repositório do GitHub para este codelab. O repositório do GitHub contém versões do código do codelab antes e depois. O codelab vai começar com um modelo de projeto vazio e criar até o estado final. Se você tiver dificuldades, use o projeto concluído no repositório como referência.
Clonar o repositório ou baixar o código
Navegue até o diretório em que você quer armazenar o codelab.
Em seguida, clone o repositório ou faça o download do código:
git clone https://github.com/googlemaps-samples/codelab-navigation-101-ios-swift
Se você não tiver o git instalado, clique neste botão para acessar o código:
Para começar o mais rápido possível, o repositório contém um código inicial na pasta Starter para ajudar você a acompanhar este codelab. Há também um projeto Solution concluído caso você queira avançar ou verificar seu progresso a qualquer momento. Para usar o projeto de solução, siga as instruções de "Instalar usando o Cocoapods" abaixo e execute o comando "pod update" na pasta solution/Navigation SDK Codelab.
Depois de clonar o repositório localmente, use o Xcode para abrir a pasta Starter como um projeto existente. Verifique se o projeto é criado e executado.
Conectar um dispositivo ou configurar o simulador do XCode
4. Adicionar o SDK Navigation ao seu app
Há três maneiras de integrar o SDK Navigation a um projeto do Xcode. Este codelab usa o CocoaPods. Para detalhes sobre como fazer a integração usando o Swift Package Manager ou instalar manualmente baixando o SDK, consulte Criar o projeto do Xcode e instalar o SDK Navigation na documentação do SDK Navigation.
Instalar usando o Cocoapods
Se você ainda não tem essa ferramenta, instale-a no macOS executando o seguinte comando no terminal. Para saber mais, consulte o Guia de primeiros passos do CocoaPods (em inglês).
sudo gem install cocoapods
Crie um arquivo chamado Podfile na pasta do projeto, dentro da pasta starter/Navigation SDK Codelab (no XCode, File > New > File > Other > Empty, salve como "Podfile")
Adicione o seguinte conteúdo ao seu Podfile:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '15.0'
target 'Navigation SDK Codelab' do
pod 'GoogleNavigation', '9.1.1'
end
Economize Podfile.
Abra um terminal e mude o diretório para o local em que você salvou o Podfile (a pasta "starter/Navigation SDK Codelab" no repositório do codelab).
cd "<path-to-starter-project-folder>/Navigation SDK Codelab"
Execute o comando pod install. Isso instala as APIs especificadas no Podfile e as respectivas dependências.
pod install
Feche o Xcode e abra o arquivo .xcworkspace do projeto para iniciar o programa. Depois disso, é preciso usar o arquivo .xcworkspace para abrir o projeto.
Verifique se um diretório "Pods" foi adicionado à estrutura do projeto e se ele contém os pods "GoogleMaps" e "GoogleNavigation".

Adicionar sua chave de API
Inclua sua chave de API ao AppDelegate.swift da seguinte maneira:
- Adicione as seguintes declarações de importação:
import GoogleMaps
import GoogleNavigation
- Adicione o seguinte ao método
application(_:didFinishLaunchingWithOptions:):
GMSServices.provideAPIKey("YOUR_API_KEY")
Substitua "YOUR_API_KEY" pela chave de API criada na etapa anterior.
Crie seu projeto e corrija os erros.
5. Configurar permissões do app
O SDK Navigation depende de sinais de GPS para fornecer localização ajustada à via e orientação curva a curva. Por isso, seu app precisa pedir ao usuário que conceda acesso a dados de localização exata.
Para isso, adicione algumas propriedades ao Info.plist dos apps no Xcode, adicione um código ao app para pedir permissão ao usuário durante a execução e processe erros, como permissão não concedida ou localização indisponível.
Abra o arquivo Info.plist no Xcode. A aparência será semelhante a esta.

Solicitar permissão de localização exata
Para adicionar novos valores, passe o ponteiro do mouse sobre a linha "Lista de propriedades de informações" até que um ícone "+" apareça. Clique no "+" para ver uma caixa de diálogo com nomes de propriedades sugeridos. Também é possível adicionar propriedades manualmente.
Adicione as seguintes propriedades e valores a Info.plist:
Propriedade | Valor |
Privacidade - Descrição de uso de localização sempre e durante o uso | "Este app precisa da localização do seu dispositivo para oferecer navegação guiada" |
Privacidade: descrição do uso de localização durante o uso | "Este app precisa da localização do seu dispositivo para oferecer navegação guiada" |
allowsBackgroundLocationUpdates | SIM |
Solicitar permissão de localização em segundo plano
Adicione as seguintes propriedades e valores a Info.plist:
UIBackgroundModes > Adicionar linha > Item 0: App registers for location updates (selecione esse valor na lista suspensa de sugestões)
O Info.plist vai ficar parecido com isso quando você terminar.

Solicitar acesso à localização no momento da execução
Adicione as seguintes declarações de importação a ViewController.swift:
import GoogleNavigation
Adicione a seguinte declaração à classe ViewController:
var locationManager: CLLocationManager!
Adicione uma substituição de método para loadView() e chame locationManager.requestAlwaysAuthorization():
override func loadView() {
locationManager = CLLocationManager()
locationManager.requestAlwaysAuthorization()
Agora, o app vai pedir a localização do usuário e disponibilizá-la se ele conceder permissão .
Solicitar permissão para mostrar notificações
Adicione o seguinte código a loadView() para pedir permissão ao usuário para mostrar notificações, o que é necessário para mostrar instruções de manobra de navegação.
UNUserNotificationCenter.current().requestAuthorization(options: [.alert]) {
granted, error in
// Handle denied authorization to display notifications.
if !granted || error != nil {
print("User rejected request to display notifications.")
}
}
Crie e execute o app e verifique se você recebe uma solicitação para compartilhar a localização e ativar as notificações.

6. Adicionar uma interface do usuário de navegação
Nesta etapa, você vai adicionar um mapa e configurá-lo para mostrar um local. Em seguida, mostre ao usuário uma caixa de diálogo com os Termos de Uso do SDK Navigation.
Adicionar uma visualização de mapa ao seu app
Adicione esta linha para declarar uma variável GMSMapView no seu ViewController.
var mapView: GMSMapView!
Adicione o seguinte código ao loadView() no Viewcontroller.swift para inicializar o mapa.
let camera = GMSCameraPosition.camera(withLatitude: 51.483174, longitude: -0.177369, zoom: 14)
let options = GMSMapViewOptions()
options.camera = camera
options.frame = .zero
mapView = GMSMapView(options: options)
view = mapView
Crie e execute o app. Você vai ver um mapa centralizado no sudoeste de Londres.

Mostrar a caixa de diálogo dos termos de uso do produto do SDK do Navigation
Adicione o código a seguir a ViewController.swift no mesmo método loadView() do código anterior. Isso vai mostrar os termos de uso do usuário final do SDK Navigation. Se não for aceito, a navegação não será ativada.
// Show the terms and conditions.
let companyName = "Navigation SDK Codelab"
GMSNavigationServices.showTermsAndConditionsDialogIfNeeded(withCompanyName: companyName) { termsAccepted in
if termsAccepted {
// Enable navigation if the user accepts the terms.
self.mapView.isNavigationEnabled = true
// Request authorization for alert notifications which deliver guidance instructions
// in the background.
} else {
// Handle the case when the user rejects the terms and conditions.
}
}
Crie e execute o app para ver a caixa de diálogo.

7. Adicionar listeners para eventos principais de navegação
Esta etapa mostra como configurar listeners para eventos principais, como a chegada a um destino ou o redirecionamento do motorista.
Para detectar esses eventos, seu controlador de visualização precisa adotar o protocolo GMSNavigatorListener.
Adicione esse protocolo à definição de classe em ViewController.swift.
class ViewController: UIViewController,
GMSNavigatorListener {
Agora, adicione uma linha de código para configurar o listener em loadView():.
// Add a listener for GMSNavigator.
mapView.navigator?.add(self)
Por fim, adicione dois métodos à classe para processar os eventos gerados.
// Listener to handle arrival events.
func navigator(_ navigator: GMSNavigator, didArriveAt waypoint: GMSNavigationWaypoint) {
print("You have arrived at: \(waypoint.title)")
}
// Listener for route change events.
func navigatorDidChangeRoute(_ navigator: GMSNavigator) {
print("The route has changed.")
}
8. Definir um destino e iniciar o trajeto
Esta seção ensina como definir um destino e iniciar o trajeto.
Crie uma nova função para a lógica de navegação.
Primeiro, adicione uma nova função chamada startNav() ao seu ViewController. Ele vai conter a lógica para definir um destino e iniciar a navegação.
// Create a route and start guidance.
@objc func startNav() {
}
Crie um Waypoint para o destino.
Em seguida, crie uma matriz de destinos com um único ponto de parada.
// Create a route and start guidance.
@objc func startNav() {
var destinations = [GMSNavigationWaypoint]()
destinations.append(
GMSNavigationWaypoint.init(
placeID: "ChIJH-tBOc4EdkgRJ8aJ8P1CUxo",
title: "Trafalgar Square")!)
}
Chame setDestinations()e processe a resposta.
Em seguida, chame setDestinations e processe o GMSRouteStatus retornado.
Se o GMSRouteStatus for "OK", inicie a orientação definindo isGuidanceActive=true no objeto navigator do mapView. Caso contrário, imprima uma instrução para mostrar que houve um erro.
Se o valor GMSRouteStatus retornado for "OK", comece a simular a direção ao longo do trajeto chamando mapView.locationSimulator.simulateLocationsAlongExistingRoute().
// Create a route and start guidance.
@objc func startNav() {
var destinations = [GMSNavigationWaypoint]()
destinations.append(
GMSNavigationWaypoint.init(
placeID: "ChIJH-tBOc4EdkgRJ8aJ8P1CUxo",
title: "Trafalgar Square")!)
mapView.navigator?.setDestinations(
destinations
) { routeStatus in
guard routeStatus == .OK else {
print("Handle route statuses that are not OK.")
return
}
//If routeStatus is OK, start guidance.
self.mapView.navigator?.isGuidanceActive = true
//start simulating driving along the route. self.mapView.locationSimulator?.simulateLocationsAlongExistingRoute()
self.mapView.cameraMode = .following
}
}
Lidar com status de erro comuns
É útil processar os erros do GMSRouteStatus de maneira mais explícita, principalmente ao depurar problemas iniciais com seu novo app. Por exemplo, você pode descobrir que recebe erros de permissão de localização, chave de API ou "nenhuma rota encontrada" com mais frequência no início devido à configuração de depuração. Portanto, pode ser útil processar esses estados de erro.
Adicione um código que processe esses casos específicos e imprima uma instrução no console.
mapView.navigator?.setDestinations(
destinations
) { routeStatus in
guard routeStatus == .OK else {
print("Handle route statuses that are not OK.")
switch routeStatus {
case .locationUnavailable:
print("Location unavailable.") //check permissions
case .noRouteFound:
print("No route found.") //check start location and destination
case .waypointError:
print("Waypoint error") //check Place ID
default:
print("Not sure what happened")
}
return
}
Adicionar um botão para iniciar a orientação de navegação
Por fim, adicione um botão à interface e conecte-o ao método startNav. Crie um método chamado makeButton() com o seguinte código. Chame a função makeButton() do loadView().
// Add a button to the view.
func makeButton() {
// A button to start navigation.
let navButton = UIButton(frame: CGRect(x: 5, y: 150, width: 200, height: 35))
navButton.backgroundColor = .blue
navButton.alpha = 0.5
navButton.setTitle("Start navigation", for: .normal)
navButton.addTarget(self, action: #selector(startNav), for: .touchUpInside)
self.mapView.addSubview(navButton)
}
Compile e execute o app.
Observação: executar o código em
startNav()
vai ligar para o
setDestinations()
método que gera uma cobrança após os primeiros 1.000 destinos usados. Consulte Uso e faturamento para mais informações.
9. Parabéns!
Parabéns, você chegou ao destino!

Você criou um app simples que oferece navegação guiada até um destino usando o SDK Navigation da Plataforma Google Maps.
Você configurou as permissões do app e a caixa de diálogo dos termos do usuário final do SDK Navigation e especificou um destino usando um ID de lugar. Você processou vários estados de sucesso e erro no seu app.
10. Como ir além
Se quiser ir além no desenvolvimento de apps, confira os tópicos a seguir para se inspirar.
- Detectar mais eventos de navegação. Adicione código para mostrar uma mensagem se o tempo ou a distância restante exceder um limite.
- Personalize a interface de navegação.
- Se quiser um desafio maior, tente adicionar um seletor de lugar da API Places para permitir que o usuário defina o destino. Dica: os apps de demonstração do SDK do Navigation têm uma implementação de exemplo. Execute
pod try GoogleNavigationna pasta do projeto para ver o código.