Criar um app de navegação iOS simples em Swift com o SDK Navigation da Plataforma Google Maps

Criar um app de navegação iOS simples em Swift com o SDK Navigation da Plataforma Google Maps

Sobre este codelab

subjectÚltimo out. 10, 2024 atualizado
account_circleEscrito por Ed Boiling

1. Antes de começar

Este codelab ensina a criar um app iOS simples que usa o SDK de navegação da Plataforma Google Maps para chegar a um destino pré-configurado.

O app vai ficar assim quando você terminar.

7e7c194a98d6dfa4.png

Pré-requisitos

O que você vai aprender

  • Como criar um app iOS Swift simples que usa o SDK do Navigation para navegar até um destino.
  • Como integrar o SDK de navegação 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 de navegação.
  • Como inicializar o SDK.
  • Como definir um destino e iniciar as orientações de navegação.

O que é necessário

  • A versão estável mais recente do XCode.
  • Uma Conta do Google e um projeto com faturamento ativado.
  • Um dispositivo iOS ou emulado em execução no XCode Simulator. Seja qual for sua escolha, ela precisa atender aos requisitos mínimos do SDK do Navigation.

2. Começar a configuração

Se você ainda não tiver uma conta do Google Cloud Platform e um projeto com faturamento ativado, configure seu projeto do Google Cloud seguindo as instruções para começar a usar a Plataforma Google Maps.

Selecionar um projeto do Google Cloud no console

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

Menu suspenso do seletor de projetos no console do Google Cloud.

Ativar o SDK do Navigation no seu projeto

Ative as APIs e os SDKs da Plataforma Google Maps necessários para este codelab no Google Cloud Marketplace.

Acesse a página APIs e Serviços > Library no console do Google Cloud e pesquise por "Navigation SDK".

Você vai encontrar um resultado de pesquisa.

Tela da biblioteca de APIs no console do Google Cloud mostrando a página do SDK do Navigation.

Clique em SDK Navigation para abrir a página "Detalhes do produto". Clique em Enable para ativar o SDK no projeto.

Repita esse processo para o SDK do 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 superior da página e selecione "Chave de API" nas opções.

Para uso em produção, é recomendável definir uma restrição de aplicativo para a chave de API, mas isso é opcional neste codelab.

3. Acesse os arquivos de projeto de amostra

Esta seção descreve como configurar um projeto básico vazio do app XCode clonando arquivos do repositório do GitHub para este codelab. O repositório do GitHub contém versões anteriores e posteriores do código do codelab. O codelab vai começar com um modelo de projeto vazio e evoluir até o estado final. Se você ficar preso, use o projeto concluído no repositório como referência.

Clone o repositório ou faça o download do 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 receber 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 da solução, siga as instruções em "Instalar usando o Cocoapods" as instruções abaixo e depois execute o comando "pod update" da pasta solution/Navigation SDK Codelab.

Depois de clonar o repositório localmente, use o XCode para abrir a pasta Starter como um projeto. Verifique se o projeto é criado e executado.

Conectar um dispositivo ou configurar o simulador de XCode

4. Adicionar o SDK de navegação ao app

Há três maneiras de integrar o SDK do Navigation a um projeto do XCode: este codelab usa CocoaPods. Para saber mais sobre como fazer a integração usando o Gerenciador de pacotes do Swift ou fazer o download do SDK manualmente, consulte Criar o projeto do Xcode e instalar o SDK do Navigation na documentação do SDK do Navigation.

Instalar usando o CocoaPods

Se você ainda não tem essa ferramenta, instale-a no macOS executando o comando a seguir no terminal. Para saber mais, consulte o Guia de primeiros passos do CocoaPods.

sudo gem install cocoapods

Crie um novo 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 seu Podfile. Essa pasta deve ser 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 todas as dependências.

pod install

Feche o Xcode e abra o arquivo .xcworkspace do seu projeto para iniciá-lo. A partir desse momento, será preciso usar o arquivo .xcworkspace para abrir o projeto.

Verifique se um diretório de pods foi adicionado à estrutura do projeto e se ele contém os pods "GoogleMaps" e "GoogleNavigation".

6e81772ee067d452.png

Adicionar sua chave de API

Inclua sua chave de API ao AppDelegate.swift da seguinte maneira:

  1. Adicione as seguintes declarações import:
import GoogleMaps
import GoogleNavigation
  1. Adicione o seguinte ao método application(_:didFinishLaunchingWithOptions:):
GMSServices.provideAPIKey("YOUR_API_KEY")

Substitua "YOUR_API_KEY" pela chave de API que você criou na etapa anterior.

Crie o projeto e corrija os erros.

5. Configurar permissões do app

O SDK de navegação depende de sinais de GPS para fornecer localização aproximada e orientação passo a passo. Portanto, seu app precisa pedir ao usuário para conceder acesso a dados de localização precisos.

Para fazer isso, você vai adicionar algumas propriedades ao Info.plist do seu app no Xcode, adicionar um código ao seu app para solicitar permissão do usuário no tempo de execução e lidar com erros como a permissão não concedida ou a indisponibilidade do local.

Abra o Info.plist no Xcode. A aparência será semelhante a esta.

6532a85bd9ac8fb4.png

Solicitar permissão de local exato

Você pode adicionar novos valores passando o cursor do mouse sobre "Lista de propriedades da informação" até ver "+" ícone aparecer. Clique no sinal "+" para ver uma caixa de diálogo com nomes de propriedades sugeridos. Também é possível adicionar propriedades manualmente.

Adicione as propriedades e os valores a seguir ao Info.plist:

Propriedade

Valor

Privacidade: descrição de uso de localização sempre e quando em uso

"Este app precisa da localização do seu dispositivo para oferecer navegação guiada"

Privacidade: descrição do uso do local quando em uso

"Este app precisa da localização do dispositivo para oferecer navegação guiada"

allowsBackgroundLocationUpdates

SIM

Pedir permissão de localização em segundo plano

Adicione as propriedades e os valores a seguir ao Info.plist:

UIBackgroundModes > Adicionar linha > Item 0: App registers for location updates (selecione este valor na lista suspensa de sugestões)

Quando você terminar, o arquivo Info.plist deve ficar assim:

3b0c49018451d0ff.png

Solicitar acesso à localização no momento da execução

Adicione as seguintes declarações de importação a ViewController.swift:

import GoogleNavigation

Adicione a declaração a seguir à 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 solicitar a localização do usuário e disponibilizá-la se ele conceder a permissão.

Pedir permissão para mostrar notificações

Adicione o código abaixo a loadView() para solicitar ao usuário a permissão de mostrar notificações, que será necessária 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.

ad5f665a21170c49.png

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, você vai mostrar ao usuário uma caixa de diálogo com os Termos de Uso do SDK do Navigation.

Adicionar uma visualização de mapa ao seu app

Adicione esta linha para declarar uma variável GMSMapView no 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.

1d46ce5c0851cae3.png

Mostrar a caixa de diálogo de termos de uso do produto do SDK do Navigation

Adicione o código abaixo 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 do Navigation. Caso contrário, 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.

29f17ae5b4c07c9f.png

7. Adicionar listeners para eventos de navegação principais

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 da classe no 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 à sua classe para lidar com os eventos que estão sendo 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. Defina um destino e inicie as orientações

Esta seção ensina a definir um destino e iniciar a navegação.

Crie uma nova função para a lógica de navegação.

Primeiro, adicione uma nova função chamada startNav() ao ViewController. Ele vai conter a lógica para definir um destino e começar a navegar.

// 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 waypoint.

// 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, mostre uma instrução para mostrar que houve um erro.

Se o valor retornado de GMSRouteStatus for "OK", comece a simular o percurso 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
  }
}

Processar status de erro comuns

É útil processar os erros GMSRouteStatus de forma mais explícita, especialmente ao depurar problemas iniciais com seu novo app. Por exemplo, você pode descobrir que está recebendo permissão de localização, chave de API ou "nenhum trajeto encontrado" erros com mais frequência no início devido à sua configuração de depuração, portanto, pode ser útil lidar com esses estados de erro.

Adicione o código que processa esses casos específicos e mostra 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()

chamará o

setDestinations()

que gera cobrança após os primeiros 1.000 destinos usados. Consulte Uso e faturamento para mais informações.

9. Parabéns!

Muito bem! Você chegou ao seu destino.

7a69dcb75c904d7.png

Você criou um app simples que oferece orientações de navegação guiada para um destino usando o SDK de navegação da Plataforma Google Maps.

Você configurou as permissões do app e a caixa de diálogo de termos do usuário final do SDK do Navigation e especificou um destino usando um ID de lugar. Você processou vários estados de sucesso e erro no app.

10. Como ir além

Se você quiser dar um passo adiante no desenvolvimento do app, confira os tópicos a seguir para se inspirar.

  • Detectar mais eventos de navegação. Adicione um código para mostrar uma mensagem se o tempo ou a distância restante exceder um limite.
  • Personalizar a interface de navegação.
  • Se você quiser um desafio maior, veja se é possível adicionar um seletor de local 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 GoogleNavigation na pasta do projeto para conferir o código.