Ao acompanhar uma viagem, o aplicativo para o consumidor mostra a localização do veículo adequado ao consumidor. Para fazer isso, o app precisa começar a acompanhar uma viagem, atualizar o progresso dela e parar de acompanhar quando ela for concluída.
Este documento aborda como esse processo funciona.
Começar a acompanhar uma viagem
Veja como começar a acompanhar uma viagem:
Reúna todas as entradas do usuário, como locais de embarque e desembarque, de um
ViewController.Crie um novo
ViewControllerpara começar a acompanhar uma viagem diretamente.
O exemplo a seguir mostra como começar a acompanhar uma viagem imediatamente após o carregamento da visualização.
Swift
/*
* MapViewController.swift
*/
override func viewDidLoad() {
super.viewDidLoad()
...
self.mapView = GMTCMapView(frame: UIScreen.main.bounds)
self.mapView.delegate = self
self.view.addSubview(self.mapView)
}
func mapViewDidInitializeCustomerState(_: GMTCMapView) {
self.mapView.pickupLocation = self.selectedPickupLocation
self.mapView.dropoffLocation = self.selectedDropoffLocation
self.startConsumerMatchWithLocations(
pickupLocation: self.mapView.pickupLocation!,
dropoffLocation: self.mapView.dropoffLocation!
) { [weak self] (tripName, error) in
guard let strongSelf = self else { return }
if error != nil {
// print error message.
return
}
let tripService = GMTCServices.shared().tripService
// Create a tripModel instance for listening the update of the trip
// specified by this trip name.
let tripModel = tripService.tripModel(forTripName: tripName)
// Create a journeySharingSession instance based on the tripModel
let journeySharingSession = GMTCJourneySharingSession(tripModel: tripModel)
// Add the journeySharingSession instance on the mapView for UI updating.
strongSelf.mapView.show(journeySharingSession)
// Register for the trip update events.
tripModel.register(strongSelf)
strongSelf.currentTripModel = tripModel
strongSelf.currentJourneySharingSession = journeySharingSession
strongSelf.hideLoadingView()
}
self.showLoadingView()
}
Objective-C
/*
* MapViewController.m
*/
- (void)viewDidLoad {
[super viewDidLoad];
...
self.mapView = [[GMTCMapView alloc] initWithFrame:CGRectZero];
self.mapView.delegate = self;
[self.view addSubview:self.mapView];
}
// Handle the callback when the GMTCMapView did initialized.
- (void)mapViewDidInitializeCustomerState:(GMTCMapView *)mapview {
self.mapView.pickupLocation = self.selectedPickupLocation;
self.mapView.dropoffLocation = self.selectedDropoffLocation;
__weak __typeof(self) weakSelf = self;
[self startTripBookingWithPickupLocation:self.selectedPickupLocation
dropoffLocation:self.selectedDropoffLocation
completion:^(NSString *tripName, NSError *error) {
__typeof(self) strongSelf = weakSelf;
GMTCTripService *tripService = [GMTCServices sharedServices].tripService;
// Create a tripModel instance for listening to updates to the trip specified by this trip name.
GMTCTripModel *tripModel = [tripService tripModelForTripName:tripName];
// Create a journeySharingSession instance based on the tripModel.
GMTCJourneySharingSession *journeySharingSession =
[[GMTCJourneySharingSession alloc] initWithTripModel:tripModel];
// Add the journeySharingSession instance on the mapView for updating the UI.
[strongSelf.mapView showMapViewSession:journeySharingSession];
// Register for trip update events.
[tripModel registerSubscriber:self];
strongSelf.currentTripModel = tripModel;
strongSelf.currentJourneySharingSession = journeySharingSession;
[strongSelf hideLoadingView];
}];
[self showLoadingView];
}
Parar de acompanhar uma viagem
Você para de acompanhar uma viagem quando ela é concluída ou cancelada. O exemplo a seguir mostra como parar de compartilhar a viagem ativa.
Swift
/*
* MapViewController.swift
*/
func cancelCurrentActiveTrip() {
// Stop the tripModel
self.currentTripModel.unregisterSubscriber(self)
// Remove the journey sharing session from the mapView's UI stack.
self.mapView.hide(journeySharingSession)
}
Objective-C
/*
* MapViewController.m
*/
- (void)cancelCurrentActiveTrip {
// Stop the tripModel
[self.currentTripModel unregisterSubscriber:self];
// Remove the journey sharing session from the mapView's UI stack.
[self.mapView hideMapViewSession:journeySharingSession];
}
Atualizar o progresso da viagem
Durante uma viagem, você gerencia o progresso da seguinte maneira:
Comece a escutar atualizações. Para conferir um exemplo, consulte Começar a escutar atualizações.
Processar atualizações de viagens. Para conferir um exemplo, consulte Processar atualizações de viagens.
Quando uma viagem é concluída ou cancelada, pare de escutar atualizações. Para conferir um exemplo, consulte Parar de escutar atualizações.
Começar a escutar atualizações
O exemplo a seguir mostra como registrar o callback tripModel.
Swift
/*
* MapViewController.swift
*/
override func viewDidLoad() {
super.viewDidLoad()
// Register for trip update events.
self.currentTripModel.register(self)
}
Objective-C
/*
* MapViewController.m
*/
- (void)viewDidLoad {
[super viewDidLoad];
// Register for trip update events.
[self.currentTripModel registerSubscriber:self];
...
}
Parar de escutar atualizações
O exemplo a seguir mostra como cancelar o registro do callback tripModel.
Swift
/*
* MapViewController.swift
*/
deinit {
self.currentTripModel.unregisterSubscriber(self)
}
Objective-C
/*
* MapViewController.m
*/
- (void)dealloc {
[self.currentTripModel unregisterSubscriber:self];
...
}
Processar atualizações de viagens
O exemplo a seguir mostra como implementar o protocolo GMTCTripModelSubscriber para processar callbacks quando o estado da viagem é atualizado.
Swift
/*
* MapViewController.swift
*/
func tripModel(_: GMTCTripModel, didUpdate trip: GMTSTrip?, updatedPropertyFields: GMTSTripPropertyFields) {
// Update the UI with the new `trip` data.
self.updateUI(with: trip)
}
func tripModel(_: GMTCTripModel, didUpdate tripStatus: GMTSTripStatus) {
// Handle trip status did change.
}
func tripModel(_: GMTCTripModel, didUpdateActiveRouteRemainingDistance activeRouteRemainingDistance: Int32) {
// Handle remaining distance of active route did update.
}
func tripModel(_: GMTCTripModel, didUpdateActiveRoute activeRoute: [GMTSLatLng]?) {
// Handle trip active route did update.
}
func tripModel(_: GMTCTripModel, didUpdate vehicleLocation: GMTSVehicleLocation?) {
// Handle vehicle location did update.
}
func tripModel(_: GMTCTripModel, didUpdatePickupLocation pickupLocation: GMTSTerminalLocation?) {
// Handle pickup location did update.
}
func tripModel(_: GMTCTripModel, didUpdateDropoffLocation dropoffLocation: GMTSTerminalLocation?) {
// Handle drop off location did update.
}
func tripModel(_: GMTCTripModel, didUpdatePickupETA pickupETA: TimeInterval) {
// Handle the pickup ETA did update.
}
func tripModel(_: GMTCTripModel, didUpdateDropoffETA dropoffETA: TimeInterval) {
// Handle the drop off ETA did update.
}
func tripModel(_: GMTCTripModel, didUpdateRemaining remainingWaypoints: [GMTSTripWaypoint]?) {
// Handle updates to the pickup, dropoff or intermediate destinations of the trip.
}
func tripModel(_: GMTCTripModel, didFailUpdateTripWithError error: Error?) {
// Handle the error.
}
func tripModel(_: GMTCTripModel, didUpdateIntermediateDestinations intermediateDestinations: [GMTSTerminalLocation]?) {
// Handle the intermediate destinations being updated.
}
func tripModel(_: GMTCTripModel, didUpdateActiveRouteTraffic activeRouteTraffic: GMTSTrafficData?) {
// Handle trip active route traffic being updated.
}
Objective-C
/*
* MapViewController.m
*/
#pragma mark - GMTCTripModelSubscriber implementation
- (void)tripModel:(GMTCTripModel *)tripModel
didUpdateTrip:(nullable GMTSTrip *)trip
updatedPropertyFields:(enum GMTSTripPropertyFields)updatedPropertyFields {
// Update the UI with the new `trip` data.
[self updateUIWithTrip:trip];
...
}
- (void)tripModel:(GMTCTripModel *)tripModel didUpdateTripStatus:(enum GMTSTripStatus)tripStatus {
// Handle trip status did change.
}
- (void)tripModel:(GMTCTripModel *)tripModel
didUpdateActiveRouteRemainingDistance:(int32_t)activeRouteRemainingDistance {
// Handle remaining distance of active route did update.
}
- (void)tripModel:(GMTCTripModel *)tripModel
didUpdateActiveRoute:(nullable NSArray<GMTSLatLng *> *)activeRoute {
// Handle trip active route did update.
}
- (void)tripModel:(GMTCTripModel *)tripModel
didUpdateVehicleLocation:(nullable GMTSVehicleLocation *)vehicleLocation {
// Handle vehicle location did update.
}
- (void)tripModel:(GMTCTripModel *)tripModel
didUpdatePickupLocation:(nullable GMTSTerminalLocation *)pickupLocation {
// Handle pickup location did update.
}
- (void)tripModel:(GMTCTripModel *)tripModel
didUpdateDropoffLocation:(nullable GMTSTerminalLocation *)dropoffLocation {
// Handle drop off location did update.
}
- (void)tripModel:(GMTCTripModel *)tripModel didUpdatePickupETA:(NSTimeInterval)pickupETA {
// Handle the pickup ETA did update.
}
- (void)tripModel:(GMTCTripModel *)tripModel
didUpdateRemainingWaypoints:(nullable NSArray<GMTSTripWaypoint *> *)remainingWaypoints {
// Handle updates to the pickup, dropoff or intermediate destinations of the trip.
}
- (void)tripModel:(GMTCTripModel *)tripModel didUpdateDropoffETA:(NSTimeInterval)dropoffETA {
// Handle the drop off ETA did update.
}
- (void)tripModel:(GMTCTripModel *)tripModel didFailUpdateTripWithError:(nullable NSError *)error {
// Handle the error.
}
- (void)tripModel:(GMTCTripModel *)tripModel
didUpdateIntermediateDestinations:
(nullable NSArray<GMTSTerminalLocation *> *)intermediateDestinations {
// Handle the intermediate destinations being updated.
}
- (void)tripModel:(GMTCTripModel *)tripModel
didUpdateActiveRouteTraffic:(nullable GMTSTrafficData *)activeRouteTraffic {
// Handle trip active route traffic being updated.
}
Processar erros de viagem
Se você assinou o tripModel e ocorreu um erro, é possível receber o callback
de tripModel implementando o método delegado
tripModel(_:didFailUpdateTripWithError:). As mensagens de erro seguem o padrão de erros do Google Cloud. Para conferir definições detalhadas de mensagens de erro
e todos os códigos de erro, consulte a
documentação de erros do Google Cloud.
Confira alguns erros comuns que podem ocorrer durante o monitoramento de viagens:
| HTTP | RPC | Descrição |
|---|---|---|
| 400 | INVALID_ARGUMENT | O cliente especificou um nome de viagem inválido. O nome da viagem precisa seguir o
formato providers/{provider_id}/trips/{trip_id}. O
provider_id precisa ser o ID do projeto do Cloud de propriedade de
o provedor de serviços. |
| 401 | UNAUTHENTICATED | Você recebe esse erro se não houver credenciais de autenticação válidas. Por exemplo, se o token JWT for assinado sem um ID de viagem ou se o token JWT tiver expirado. |
| 403 | PERMISSION_DENIED | Você recebe esse erro se o cliente não tiver permissão suficiente (por exemplo, um usuário com a função de consumidor tenta chamar updateTrip), se o token JWT for inválido ou se a API não estiver ativada para o projeto do cliente. O token JWT pode estar ausente ou assinado com um ID de viagem que não corresponde ao ID de viagem solicitado. |
| 429 | RESOURCE_EXHAUSTED | A cota de recursos está em zero ou a taxa de tráfego excede o limite. |
| 503 | UNAVAILABLE | Serviço indisponível. Geralmente, o servidor está desativado. |
| 504 | DEADLINE_EXCEEDED | O prazo de solicitação foi excedido. Esse erro só ocorre se o chamador definir um prazo menor que o prazo padrão do método (ou seja, o prazo solicitado não é suficiente para o servidor processar a solicitação) e a solicitação não for concluída dentro do prazo. |
Processar erros do SDK do consumidor
O SDK do consumidor envia erros de atualização de viagens para o aplicativo para o consumidor usando um mecanismo de callback. O parâmetro de callback é um tipo de retorno específico da plataforma (
TripUpdateError
no Android e
NSError
no iOS).
Extrair códigos de status
Os erros transmitidos ao callback geralmente são erros de gRPC, e também é possível extrair mais informações deles na forma de um código de status. Para conferir a lista completa de códigos de status, consulte Códigos de status e uso no gRPC.
Swift
O NSError é chamado de volta em tripModel(_:didFailUpdateTripWithError:).
// Called when there is a trip update error.
func tripModel(_ tripModel: GMTCTripModel, didFailUpdateTripWithError error: Error?) {
// Check to see if the error comes from gRPC.
if let error = error as NSError?, error.domain == "io.grpc" {
let gRPCErrorCode = error.code
...
}
}
Objective-C
O NSError é chamado de volta em tripModel:didFailUpdateTripWithError:.
// Called when there is a trip update error.
- (void)tripModel:(GMTCTripModel *)tripModel didFailUpdateTripWithError:(NSError *)error {
// Check to see if the error comes from gRPC.
if ([error.domain isEqualToString:@"io.grpc"]) {
NSInteger gRPCErrorCode = error.code;
...
}
}
Interpretar códigos de status
Os códigos de status abrangem dois tipos de erros: erros relacionados ao servidor e à rede e erros do lado do cliente.
Erros de servidor e rede
Os códigos de status a seguir são para erros de rede ou de servidor, e não é necessário tomar nenhuma ação para resolvê-los. O SDK do consumidor se recupera deles automaticamente.
| Código de status | Descrição |
|---|---|
| ABORTED | O servidor parou de enviar a resposta. Isso normalmente é causado por um problema no servidor. |
| CANCELADO | O servidor encerrou a resposta de saída. Isso normalmente
acontece quando
o aplicativo é enviado para o segundo plano ou quando há uma mudança de estado no aplicativo para o consumidor. |
| INTERRUPTED | |
| DEADLINE_EXCEEDED | O servidor demorou muito para responder. |
| INDISPONÍVEL | O servidor estava indisponível. Isso normalmente é causado por um problema de rede. |
Erros do cliente
Os códigos de status a seguir são para erros do cliente, e você precisa tomar medidas para resolvê-los. O SDK do consumidor continua tentando atualizar a viagem até que você encerre o compartilhamento da jornada, mas não será recuperado até que você tome medidas.
| Código de status | Descrição |
|---|---|
| INVALID_ARGUMENT | O aplicativo para o consumidor especificou um nome de viagem inválido. O nome da viagem precisa
seguir o formato providers/{provider_id}/trips/{trip_id}.
|
| NOT_FOUND | A viagem nunca foi criada. |
| PERMISSION_DENIED | O aplicativo para o consumidor não tem permissões suficientes. Esse erro ocorre quando:
|
| RESOURCE_EXHAUSTED | A cota de recursos está em zero ou a taxa de fluxo de tráfego excede o limite de velocidade. |
| UNAUTHENTICATED | A solicitação falhou na autenticação devido a um token JWT inválido. Esse erro ocorre quando o token JWT é assinado sem um ID de viagem ou quando o token JWT expirou. |