Primeiros passos com o SDK do driver para iOS

Você pode usar o SDK do Driver para oferecer navegação e rastreamento aprimorados ao seu aplicativo de viagem e andamento do pedido. O SDK do Driver fornece atualizações de local e tarefas de veículos ao mecanismo de frota da solução de viagens e entregas sob demanda.

O SDK do Driver mantém os serviços do Fleet Engine e seus serviços personalizados cientes da localização e do estado do veículo. Por exemplo, o veículo pode ser ONLINE ou OFFLINE, e a localização dele muda conforme a viagem progride.

Requisitos mínimos do sistema

  • O dispositivo móvel precisa ter o iOS 14 ou mais recente.
  • Xcode versão 15 ou mais recente.
  • Pré-requisitos

    Este guia pressupõe que seu app já implementa o SDK de navegação e que o back-end do Fleet Engine está configurado e disponível. No entanto, o código de exemplo apresenta uma amostra de como configurar o SDK do Navigation.

    Também é necessário ativar o SDK do Maps para iOS no projeto do Google Cloud e Gerar uma chave de API.

    Configuração do projeto

    Gerenciador de pacotes do Swift

    O SDK do Driver pode ser instalado usando o Gerenciador de pacotes do Swift. Para adicionar o SDK, verifique se você removeu todas as dependências atuais do SDK do driver.

    Para adicionar o SDK a um projeto novo ou existente, siga estas etapas:

    1. Abra o Xcode project ou workspace e acesse File > Add Package Dependencies.
    2. Digite https://github.com/googlemaps/ios-driver-sdk como o URL, pressione Enter para extrair o pacote e clique em "Adicionar pacote".
    3. Para instalar um version específico, defina o campo Regra de dependência como uma das opções baseadas em versão. Para novos projetos, recomendamos especificar a versão mais recente e usar a opção "Versão exata". Quando terminar, clique em "Adicionar pacote".
    4. Na janela Choose Package Products, verifique se GoogleRidesharingDriver vai ser adicionado ao destino main designado. Quando terminar, clique em "Adicionar pacote".
    5. Para verificar a instalação, navegue até o painel General do destino. Em Frameworks, bibliotecas e conteúdo incorporado, você encontra os pacotes instalados. Você também pode ver a seção "Dependências de pacotes" do "Navegador do projeto" para verificar o pacote e a versão dele.

    Para atualizar o package de um projeto existente, siga estas etapas:

    1. No Xcode, acesse "File > Packages > Update To latest Package Versions".
    2. Para verificar a instalação, vá para a seção Dependências de pacotes do Navegador do projeto para verificar o pacote e a versão dele.

    Para remover as dependências do SDK do driver adicionadas usando CocoaPods, siga estas etapas:

    1. Feche o espaço de trabalho do Xcode. Abra o terminal e execute o seguinte comando:
      sudo gem install cocoapods-deintegrate cocoapods-clean 
      pod deintegrate 
      pod cache clean --all
    2. Remova Podfile, Podfile.resolved e workspace do Xcode se eles não forem usados para outra finalidade que não seja CocoaPods.

    Para remover o SDK do Driver existente instalado manualmente, siga estas etapas:

    1. Nas configurações do projeto do Xcode, encontre Frameworks, bibliotecas e conteúdo incorporado. Use o sinal de menos(-) para remover a estrutura a seguir:

      • GoogleRidesharingDriver.xcframework
    2. No diretório de nível superior do seu projeto Xcode, remova o pacote GoogleRidesharingDriver.

    CocoaPods

    Para configurar o SDK do driver usando o CocoaPods, você precisa dos seguintes itens:

    • A ferramenta CocoaPods: para instalar esta ferramenta, abra o terminal e execute o comando a seguir.
       sudo gem install cocoapods
    
    1. Crie um Podfile para o SDK do driver e use-o para instalar a API e as dependências dela. Crie um arquivo chamado Podfile no diretório do projeto. Esse arquivo define as dependências do seu projeto. Edite o Podfile e adicione as dependências. Veja um exemplo que inclui as dependências:

      source "https://github.com/CocoaPods/Specs.git"
      
      target 'YOUR_APPLICATION_TARGET_NAME_HERE' do
        pod 'GoogleRidesharingDriver'
      end
      

      Aqui está um exemplo que inclui os pods Alfa e Beta do SDK do Driver como dependências:

      source "https://cpdc-eap.googlesource.com/ridesharing-driver-sdk.git"
      source "https://github.com/CocoaPods/Specs.git"
      
      target 'YOUR_APPLICATION_TARGET_NAME_HERE' do
        pod 'GoogleRidesharingDriver'
      end
      
    2. Salve o Podfile. Abra um terminal e acesse o diretório que contém o Podfile:

      cd <path-to-project>
      
    3. Execute o comando de instalação do pod. Isso instalará as APIs especificadas no Podfile com as respectivas dependências.

      pod install
      
    4. Feche o Xcode e clique duas vezes no arquivo .xcworkspace do seu projeto para iniciar o Xcode. A partir desse momento, você precisará usar o arquivo .xcworkspace para abrir o projeto.

    Consulte o Guia de primeiros passos do CocoaPods para mais detalhes.

    Instalação manual

    Um XCFramework é um pacote binário usado para instalar o SDK do Driver. É possível usar esse pacote em várias plataformas, incluindo máquinas que usam o Apple Silicon. Este guia mostra como adicionar manualmente o XCFramework que contém o SDK do Driver ao seu projeto e definir as configurações de build no Xcode.

    Faça o download do binário e dos recursos do SDK:

    1. Extraia os arquivos para acessar o XCFramework e os recursos.

    2. Inicie o Xcode e abra um projeto existente ou crie um novo. Se você não tem experiência com o iOS, crie um novo projeto e selecione o modelo de app iOS.

    3. Crie um grupo do Frameworks no seu grupo de projeto, caso ainda não tenha um.

    4. Para instalar o SDK do driver, arraste o arquivo GoogleRidesharingDriver.xcframework para o projeto em Frameworks, bibliotecas e conteúdo incorporado. Quando solicitado, selecione Copiar itens, se necessário.

    5. Arraste o GoogleRidesharingDriver.bundle salvo para o diretório de nível superior do seu projeto Xcode. Quando solicitado, selecione Copy items if needed.

    6. Selecione o projeto no Navegador de projetos e escolha o alvo do aplicativo.

    7. Abra a guia "Fases de build" e, em "Vincular binário a bibliotecas", adicione os frameworks e bibliotecas a seguir, se ainda não estiverem presentes:

      • Accelerate.framework
      • AudioToolbox.framework
      • AVFoundation.framework
      • CoreData.framework
      • CoreGraphics.framework
      • CoreLocation.framework
      • CoreTelephony.framework
      • CoreText.framework
      • GLKit.framework
      • ImageIO.framework
      • libc++.tbd
      • libxml2.tbd
      • libz.tbd
      • LocalAuthentication.framework
      • OpenGLES.framework
      • QuartzCore.framework
      • SystemConfiguration.framework
      • UIKit.framework
      • WebKit.framework
    8. Escolha seu projeto, em vez de um destino específico, e abra a guia Build Settings. Na seção Outras sinalizações do vinculador, adicione -ObjC para depuração e lançamento. Se essas configurações não estiverem visíveis, mude o filtro na barra "Build Settings" de Basic para All.

    Adicionar arquivo de manifesto de privacidade da Apple

    1. Faça o download do pacote do Manifesto de privacidade do SDK do Driver para iOS: GoogleRidesharingDriverPrivacy.
    2. Extraia o arquivo para acessar GoogleRidesharingDriverPrivacy.bundle.
    3. Adicione GoogleRidesharingDriverPrivacy.bundle ao navegador do projeto Xcode usando um destes métodos. Confira se a caixa "Adicionar aos destinos" está marcada para o destino do app. Depois de adicionado, o arquivo PrivacyInfo aparece no navegador do projeto e você pode inspecionar os valores.
    4. Captura de tela das informações de privacidade do Xcode
    5. Verifique se o manifesto de privacidade foi adicionado criando um arquivo do app e gerando um relatório de privacidade a partir do arquivo.

    Implementar autorização e autenticação

    Quando o app do driver gera e envia atualizações para o back-end do Fleet Engine, as solicitações precisam incluir tokens de acesso válidos. Para autorizar e autenticar essas solicitações, o SDK do driver chama seu objeto em conformidade com o protocolo GMTDAuthorization. O objeto é responsável por fornecer o token de acesso necessário.

    Como desenvolvedor do app, você escolhe como os tokens são gerados. Sua implementação precisa oferecer a capacidade de fazer o seguinte:

    • Busque um token de acesso, possivelmente no formato JSON, de um servidor HTTPS.
    • analisar e armazenar em cache o token;
    • Atualizar o token quando ele expirar.

    Para detalhes sobre os tokens esperados pelo servidor do Fleet Engine, consulte Como criar um JSON Web Token (JWT) para autorização.

    O ID do provedor é o mesmo que o ID do projeto do Google Cloud. Consulte o Guia de início rápido do Fleet Engine para mais informações.

    O exemplo a seguir implementa um provedor de token de acesso:

    Swift

    import GoogleRidesharingDriver
    
    private let providerURL = "INSERT_YOUR_TOKEN_PROVIDER_URL"
    
    class SampleAccessTokenProvider: NSObject, GMTDAuthorization {
      private struct AuthToken {
        // The cached vehicle token.
        let token: String
        // Keep track of when the token expires for caching.
        let expiration: TimeInterval
        // Keep track of the vehicle ID the cached token is for.
        let vehicleID: String
      }
    
      enum AccessTokenError: Error {
        case missingAuthorizationContext
        case missingData
      }
    
      private var authToken: AuthToken?
    
      func fetchToken(
        with authorizationContext: GMTDAuthorizationContext?,
        completion: @escaping GMTDAuthTokenFetchCompletionHandler
      ) {
        // Get the vehicle ID from the authorizationContext. This is set by the Driver SDK.
        guard let authorizationContext = authorizationContext else {
          completion(nil, AccessTokenError.missingAuthorizationContext)
          return
        }
        let vehicleID = authorizationContext.vehicleID
    
        // If appropriate, use the cached token.
        if let authToken = authToken,
          authToken.expiration > Date.now.timeIntervalSince1970 && authToken.vehicleID == vehicleID
        {
          completion(authToken.token, nil)
          return
        }
    
        // Otherwise, try to fetch a new token from your server.
        let request = URLRequest(url: URL(string: providerURL))
        let task = URLSession.shared.dataTask(with: request) { [weak self] data, _, error in
          guard let strongSelf = self else { return }
          guard error == nil else {
            completion(nil, error)
            return
          }
    
          // Replace the following key values with the appropriate keys based on your
          // server's expected response.
          let vehicleTokenKey = "VEHICLE_TOKEN_KEY"
          let tokenExpirationKey = "TOKEN_EXPIRATION"
          guard let data = data,
            let fetchData = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
            let token = fetchData[vehicleTokenKey] as? String,
            let expiration = fetchData[tokenExpirationKey] as? Double
          else {
            completion(nil, AccessTokenError.missingData)
            return
          }
    
          strongSelf.authToken = AuthToken(
            token: token, expiration: expiration, vehicleID: vehicleID)
          completion(token, nil)
        }
        task.resume()
      }
    }
    

    Objective-C

    #import "SampleAccessTokenProvider.h"
    #import <GoogleRidesharingDriver/GoogleRidesharingDriver.h>
    
    // SampleAccessTokenProvider.h
    @interface SampleAccessTokenProvider : NSObject<GMTDAuthorization>
    @end
    
    static NSString *const PROVIDER_URL = @"INSERT_YOUR_TOKEN_PROVIDER_URL";
    
    // SampleAccessTokenProvider.m
    @implementation SampleAccessTokenProvider{
      // The cached vehicle token.
      NSString *_cachedVehicleToken;
      // Keep track of the vehicle ID the cached token is for.
      NSString *_lastKnownVehicleID;
      // Keep track of when tokens expire for caching.
      NSTimeInterval _tokenExpiration;
    }
    
    -   (void)fetchTokenWithContext:(nullable GMTDAuthorizationContext *)authorizationContext
                       completion:(nonnull GMTDAuthTokenFetchCompletionHandler)completion {
      // Get the vehicle ID from the authorizationContext. This is set by the Driver SDK.
      NSString *vehicleID = authorizationContext.vehicleID;
      if (!vehicleID) {
        NSAssert(NO, @"Vehicle ID is missing from authorizationContext.");
        return;
      }
    
      // Clear cached vehicle token if vehicle ID has changed.
      if (![_lastKnownVehicleID isEqual:vehicleID]) {
        _tokenExpiration = 0.0;
        _cachedVehicleToken = nil;
      }
      _lastKnownVehicleID = vehicleID;
    
      // Clear cached vehicletoken if it has expired.
      if ([[NSDate date] timeIntervalSince1970] > _tokenExpiration) {
        _cachedVehicleToken = nil;
      }
    
      // If appropriate, use the cached token.
      if (_cachedVehicleToken) {
        completion(_cachedVehicleToken, nil);
        return;
      }
      // Otherwise, try to fetch a new token from your server.
      NSURL *requestURL = [NSURL URLWithString:PROVIDER_URL];
      NSMutableURLRequest *request =
          [[NSMutableURLRequest alloc] initWithURL:requestURL];
      request.HTTPMethod = @"GET";
      // Replace the following key values with the appropriate keys based on your
      // server's expected response.
      NSString *vehicleTokenKey = @"VEHICLE_TOKEN_KEY";
      NSString *tokenExpirationKey = @"TOKEN_EXPIRATION";
      __weak typeof(self) weakSelf = self;
      void (^handler)(NSData *_Nullable data, NSURLResponse *_Nullable response,
                      NSError *_Nullable error) =
          ^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) {
            typeof(self) strongSelf = weakSelf;
            if (error) {
              completion(nil, error);
              return;
            }
    
            NSError *JSONError;
            NSMutableDictionary *JSONResponse =
                [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&JSONError];
    
            if (JSONError) {
              completion(nil, JSONError);
              return;
            } else {
              // Sample code only. No validation logic.
              id expirationData = JSONResponse[tokenExpirationKey];
              if ([expirationData isKindOfClass:[NSNumber class]]) {
                NSTimeInterval expirationTime = ((NSNumber *)expirationData).doubleValue;
                strongSelf->_tokenExpiration = [[NSDate date] timeIntervalSince1970] + expirationTime;
              }
              strongSelf->_cachedVehicleToken = JSONResponse[vehicleTokenKey];
              completion(JSONResponse[vehicleTokenKey], nil);
            }
          };
      NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
      NSURLSession *mainQueueURLSession =
          [NSURLSession sessionWithConfiguration:config delegate:nil
                                   delegateQueue:[NSOperationQueue mainQueue]];
      NSURLSessionDataTask *task = [mainQueueURLSession dataTaskWithRequest:request completionHandler:handler];
      [task resume];
    }
    
    @end
    

    Criar uma instância da API RidesharingDriverAPI

    Para ter uma instância do GMTDVehicleReporter, primeiro você precisa criar uma instância do GMTDRidesharingDriverAPI usando o providerID, o ID do veículo, o driverContext e o accessTokenProvider. O providerID é igual ao ID do projeto do Google Cloud. E você pode acessar a instância GMTDVehicleReporter diretamente da API do driver.

    O exemplo a seguir cria uma instância GMTDRidesharingDriverAPI:

    Swift

    import GoogleRidesharingDriver
    
    private let providerID = "INSERT_YOUR_PROVIDER_ID"
    
    class SampleViewController: UIViewController {
      private let mapView: GMSMapView
    
      override func viewDidLoad() {
        super.viewDidLoad()
    
        let vehicleID = "INSERT_CREATED_VEHICLE_ID"
        let accessTokenProvider = SampleAccessTokenProvider()
        let driverContext = GMTDDriverContext(
          accessTokenProvider: accessTokenProvider,
          providerID: providerID,
          vehicleID: vehicleID,
          navigator: mapView.navigator)
        let ridesharingDriverAPI = GMTDRidesharingDriverAPI(driverContext: driverContext)
      }
    }
    

    Objective-C

    #import "SampleViewController.h"
    #import "SampleAccessTokenProvider.h"
    #import <GoogleRidesharingDriver/GoogleRidesharingDriver.h>
    
    static NSString *const PROVIDER_ID = @"INSERT_YOUR_PROVIDER_ID";
    
    @implementation SampleViewController {
      GMSMapView *_mapView;
    }
    
    -   (void)viewDidLoad {
      NSString *vehicleID = @"INSERT_CREATED_VEHICLE_ID";
      SampleAccessTokenProvider *accessTokenProvider =
                                    [[SampleAccessTokenProvider alloc] init];
      GMTDDriverContext *driverContext =
        [[GMTDDriverContext alloc] initWithAccessTokenProvider:accessTokenProvider
                                                    providerID:PROVIDER_ID
                                                     vehicleID:vehicleID
                                                     navigator:_mapView.navigator];
    
      GMTDRidesharingDriverAPI *ridesharingDriverAPI = [[GMTDRidesharingDriverAPI alloc] initWithDriverContext:driverContext];
    }
    

    Como opção, detectar eventos do VehicleReporter

    O GMTDVehicleReporter atualiza o veículo periodicamente quando locationTrackingEnabled é true. Para responder a essas atualizações periódicas, qualquer objeto pode se inscrever em eventos GMTDVehicleReporter seguindo o protocolo GMTDVehicleReporterListener.

    É possível processar os seguintes eventos:

    • vehicleReporter(_:didSucceed:)

      Informa ao app do motorista que os serviços de back-end receberam a atualização do local e do estado do veículo.

    • vehicleReporter(_:didFail:withError:)

      Informa ao listener que uma atualização de veículo falhou. Enquanto o rastreamento de localização estiver ativado, o GMTDVehicleReporter continuará enviando os dados mais recentes para o back-end do Fleet Engine.

    O exemplo a seguir lida com esses eventos:

    Swift

    import GoogleRidesharingDriver
    
    private let providerID = "INSERT_YOUR_PROVIDER_ID"
    
    class SampleViewController: UIViewController, GMTDVehicleReporterListener {
      private let mapView: GMSMapView
    
      override func viewDidLoad() {
        // Assumes you have implemented the sample code up to this step.
        ridesharingDriverAPI.vehicleReporter.add(self)
      }
    
      func vehicleReporter(_ vehicleReporter: GMTDVehicleReporter, didSucceed vehicleUpdate: GMTDVehicleUpdate) {
        // Handle update succeeded.
      }
    
      func vehicleReporter(_ vehicleReporter: GMTDVehicleReporter, didFail vehicleUpdate: GMTDVehicleUpdate, withError error: Error) {
        // Handle update failed.
      }
    }
    

    Objective-C

    /*
    
        *   SampleViewController.h
     */
    @interface SampleViewController : UIViewController<GMTDVehicleReporterListener>
    @end
    
    /*
    
        *   SampleViewController.m
     */
    #import "SampleViewController.h"
    #import "SampleAccessTokenProvider.h"
    #import <GoogleRidesharingDriver/GoogleRidesharingDriver.h>
    
    static NSString *const PROVIDER_ID = @"INSERT_YOUR_PROVIDER_ID";
    
    @implementation SampleViewController {
      GMSMapView *_mapView;
    }
    
    -   (void)viewDidLoad {
      // Assumes you have implemented the sample code up to this step.
      [ridesharingDriverAPI.vehicleReporter addListener:self];
    }
    
    -   (void)vehicleReporter:(GMTDVehicleReporter *)vehicleReporter didSucceedVehicleUpdate:(GMTDVehicleUpdate *)vehicleUpdate {
      // Handle update succeeded.
    }
    
    -   (void)vehicleReporter:(GMTDVehicleReporter *)vehicleReporter didFailVehicleUpdate:(GMTDVehicleUpdate *)vehicleUpdate withError:(NSError *)error {
      // Handle update failed.
    }
    
    @end
    

    Adiciona GMTDVehicleReporter como um listener do GMSRoadSnappedLocationProvider

    Para fornecer atualizações de localização ao SDK do Driver, o GMTDVehicleReporter precisa ser definido como um listener do GMSRoadSnappedLocationProvider.

    Swift

    import GoogleRidesharingDriver
    
    private let providerID = "INSERT_YOUR_PROVIDER_ID"
    
    class SampleViewController: UIViewController, GMTDVehicleReporterListener {
      private let mapView: GMSMapView
    
      override func viewDidLoad() {
        // Assumes you have implemented the sample code up to this step.
        if let roadSnappedLocationProvider = mapView.roadSnappedLocationProvider {
          roadSnappedLocationProvider.add(ridesharingDriverAPI.vehicleReporter)
          roadSnappedLocationProvider.startUpdatingLocation()
        }
      }
    }
    

    Objective-C

    /*
    
        *   SampleViewController.h
     */
    @interface SampleViewController : UIViewController<GMTDVehicleReporterListener>
    @end
    
    /*
    
        *   SampleViewController.m
     */
    #import "SampleViewController.h"
    #import "SampleAccessTokenProvider.h"
    #import <GoogleRidesharingDriver/GoogleRidesharingDriver.h>
    
    static NSString *const PROVIDER_ID = @"INSERT_YOUR_PROVIDER_ID";
    
    @implementation SampleViewController {
      GMSMapView *_mapView;
    }
    
    -   (void)viewDidLoad {
      // Assumes you have implemented the sample code up to this step.
      [_mapView.roadSnappedLocationProvider addListener:ridesharingDriverAPI.vehicleReporter];
      [_mapView.roadSnappedLocationProvider startUpdatingLocation];
    }
    
    @end
    

    Ativar rastreamento de localização

    Para ativar o rastreamento de localização, seu app pode definir locationTrackingEnabled como true em GMTDVehicleReporter. O GMTDVehicleReporter envia atualizações de local automaticamente. Depois que os serviços são correspondentes e atribuem o veículo a uma viagem, o GMTDVehicleReporter envia atualizações de trajeto automaticamente quando GMSNavigator está no modo de navegação (quando um destino é definido pelo setDestinations).

    O trajeto definido durante a atualização será o mesmo que o motorista estiver seguindo durante a sessão de navegação. Assim, para que o compartilhamento de jornada funcione corretamente, o waypoint definido por setDestinations precisa corresponder ao destino definido no back-end do Fleet Engine.

    Se locationTrackingEnabled for definido como true, as atualizações de viagens e veículos serão enviadas ao back-end do Fleet Engine em um intervalo regular com base no valor definido para locationUpdateInterval. Se locationTrackingEnabled for definido como false, as atualizações serão interrompidas e uma solicitação final de atualização do veículo será enviada ao back-end do Fleet Engine para definir o estado do veículo como GMTDVehicleState.offline. Consulte updateVehicleState para considerações especiais sobre como lidar com falhas quando locationTrackingEnabled está definido como false.

    O exemplo a seguir ativa o rastreamento de localização:

    Swift

    import GoogleRidesharingDriver
    
    private let providerID = "INSERT_YOUR_PROVIDER_ID"
    
    class SampleViewController: UIViewController, GMTDVehicleReporterListener {
      private let mapView: GMSMapView
    
      override func viewDidLoad() {
        // Assumes you have implemented the sample code up to this step.
        ridesharingDriverAPI.vehicleReporter.locationTrackingEnabled = true
      }
    }
    

    Objective-C

    /*
        *   SampleViewController.m
     */
    #import "SampleViewController.h"
    #import "SampleAccessTokenProvider.h"
    #import <GoogleRidesharingDriver/GoogleRidesharingDriver.h>
    
    static NSString *const PROVIDER_ID = @"INSERT_YOUR_PROVIDER_ID";
    
    @implementation SampleViewController {
      GMSMapView *_mapView;
    }
    
    -   (void)viewDidLoad {
      // Assumes you have implemented the sample code up to this step.
      ridesharingDriverAPI.vehicleReporter.locationTrackingEnabled = YES;
    }
    
    @end
    

    Por padrão, o intervalo do relatório é de 10 segundos, mas pode ser alterado com locationUpdateInterval. O intervalo mínimo de atualização permitido é de cinco segundos. O intervalo máximo de atualização permitido é de 60 segundos. Atualizações mais frequentes podem resultar em solicitações mais lentas e erros.

    Atualizar o estado do veículo

    O exemplo abaixo mostra como definir o estado do veículo como ONLINE. Consulte updateVehicleState para ver mais detalhes.

    Swift

    import GoogleRidesharingDriver
    
    private let providerID = "INSERT_YOUR_PROVIDER_ID"
    
    class SampleViewController: UIViewController, GMTDVehicleReporterListener {
      private let mapView: GMSMapView
    
      override func viewDidLoad() {
        // Assumes you have implemented the sample code up to this step.
        ridesharingDriverAPI.vehicleReporter.update(.online)
      }
    }
    

    Objective-C

    #import "SampleViewController.h"
    #import "SampleAccessTokenProvider.h"
    #import <GoogleRidesharingDriver/GoogleRidesharingDriver.h>
    
    static NSString *const PROVIDER_ID = @"INSERT_YOUR_PROVIDER_ID";
    
    @implementation SampleViewController {
      GMSMapView *_mapView;
    }
    
    -   (void)viewDidLoad {
      // Assumes you have implemented the sample code up to this step.
      [ridesharingDriverAPI.vehicleReporter
                                       updateVehicleState:GMTDVehicleStateOnline];
    }
    
    @end
    

    Um erro update_mask pode ocorrer quando a máscara está vazia e normalmente ocorre na primeira atualização após a inicialização. O exemplo a seguir mostra como processar esse erro:

    Swift

    import GoogleRidesharingDriver
    
    class VehicleReporterListener: NSObject, GMTDVehicleReporterListener {
      func vehicleReporter(
        _ vehicleReporter: GMTDVehicleReporter,
        didFail vehicleUpdate: GMTDVehicleUpdate,
        withError error: Error
      ) {
        let fullError = error as NSError
        if let innerError = fullError.userInfo[NSUnderlyingErrorKey] as? NSError {
          let innerFullError = innerError as NSError
          if innerFullError.localizedDescription.contains("update_mask cannot be empty") {
            emptyMaskUpdates += 1
            return
          }
        }
        failedUpdates += 1
      }
    
      override init() {
        emptyMaskUpdates = 0
        failedUpdates = 0
      }
    }
    
    

    Objective-C

    #import "VehicleReporterListener.h"
    #import <GoogleRidesharingDriver/GoogleRidesharingDriver.h>
    
    @implementation VehicleReporterListener {
      NSInteger emptyMaskUpdates = 0;
      NSInteger failedUpdates = 0;
    }
    
    -   (void)vehicleReporter:(GMTDVehicleReporter *)vehicleReporter
       didFailVehicleUpdate:(GMTDVehicleUpdate *)vehicleUpdate
                  withError:(NSError *)error {
      for (NSError *underlyingError in error.underlyingErrors) {
        if ([underlyingError.localizedDescription containsString:@"update_mask cannot be empty"]) {
          emptyMaskUpdates += 1;
          return;
        }
      }
      failedUpdates += 1
    }
    
    @end
    

    Desativar atualizações de localização e deixar o veículo off-line

    O app pode desativar as atualizações e deixar o veículo off-line. Por exemplo, quando o horário do motorista termina, o app pode definir locationTrackingEnabled como false. A desativação das atualizações também define o status do veículo como OFFLINE no back-end do Fleet Engine.

    Swift

    vehicleReporter.locationTrackingEnabled = false
    

    Objective-C

    _vehicleReporter.locationTrackingEnabled = NO;