Cuando sigues un viaje, tu app para consumidores muestra la ubicación de la vehículo apropiado para el consumidor. Para ello, tu app debe iniciarse seguir un viaje, actualizar el progreso del viaje y dejar de seguirlo cuando de datos completados.
En este documento, se explica cómo funciona ese proceso.
Cómo comenzar a seguir un viaje
A continuación, te mostramos cómo comenzar a seguir un viaje con la función para compartir viajes:
Recopila todas las entradas del usuario, como las ubicaciones de entrega y de partida, desde un
ViewController
.Crea un
ViewController
nuevo para comenzar a compartir el recorrido directamente.
En el siguiente ejemplo, se muestra cómo comenzar a compartir un recorrido inmediatamente después de la Ver cargas.
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];
}
Cómo dejar de seguir un viaje
Dejas de seguir un viaje cuando se completa o se cancela. Lo siguiente ejemplo muestra cómo dejar de compartir el viaje activo.
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];
}
Actualiza el progreso del viaje
Durante un viaje, administras su progreso de la siguiente manera:
Comienza a detectar actualizaciones. Para ver un ejemplo, consulta Ejemplo de Comienza a detectar actualizaciones.
Administra las actualizaciones de viaje. Para ver un ejemplo, consulta Ejemplo de cómo controlar las actualizaciones de viaje
Cuando se completa o se cancela un viaje, deja de escuchar actualizaciones. Para ver un ejemplo, consulta Ejemplo de cómo dejar de escuchar actualizaciones.
Ejemplo de cómo comenzar a escuchar actualizaciones
En el siguiente ejemplo, se muestra cómo registrar la devolución de llamada de 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];
...
}
Ejemplo sobre cómo dejar de escuchar actualizaciones
En el siguiente ejemplo, se muestra cómo cancelar el registro de la devolución de llamada de tripModel
.
Swift
/*
* MapViewController.swift
*/
deinit {
self.currentTripModel.unregisterSubscriber(self)
}
Objective-C
/*
* MapViewController.m
*/
- (void)dealloc {
[self.currentTripModel unregisterSubscriber:self];
...
}
Ejemplo de control de actualizaciones de viajes
En el siguiente ejemplo, se muestra cómo implementar GMTCTripModelSubscriber
protocolo para manejar devoluciones de llamada cuando se actualiza el estado del viaje.
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.
}
Maneja errores de viajes
Si te suscribiste a tripModel
y se produce un error, puedes obtener la devolución de llamada de tripModel
implementando el método delegado tripModel(_:didFailUpdateTripWithError:)
. Error
mensajes siguen el estándar de Google Cloud Error. Para obtener información sobre los errores
las definiciones de mensajes y todos los códigos de error, consulta
Documentación de errores de Google Cloud.
Estos son algunos errores comunes que pueden ocurrir durante la supervisión de viajes:
HTTP | RPC | Descripción |
---|---|---|
400 | INVALID_ARGUMENT | El cliente especificó un nombre de viaje no válido. El nombre del viaje debe seguir el
formato providers/{provider_id}/trips/{trip_id} . El
provider_id debe ser el ID del proyecto de Cloud que pertenece a
el proveedor de servicios. |
401 | UNAUTHENTICATED | Recibirás este error si no hay credenciales de autenticación válidas. Por ejemplo, si el token JWT se firma sin un ID de viaje o el token JWT ha caducado. |
403 | PERMISSION_DENIED | Recibirás este error si el cliente no tiene los permisos necesarios (por ejemplo, un usuario con el rol de consumidor intenta llamar a updateTrip) si El token JWT no es válido o la API no está habilitada para el proyecto del cliente. Es posible que falte el token JWT o que el token esté firmado con un ID de viaje no coincide con el ID de viaje solicitado. |
429 | RESOURCE_EXHAUSTED | La cuota de recursos es de cero o la frecuencia de tráfico excede el límite. |
503 | NO DISPONIBLE | Servicio no disponible. Por lo general, el servidor no está en funcionamiento. |
504 | DEADLINE_EXCEEDED | Se excedió el plazo de la solicitud. Este error solo ocurre si el emisor establece un que sea menor que el plazo predeterminado del método (es decir, el el plazo solicitado no es suficiente para que el servidor procese la solicitud). la solicitud no finalizó dentro del plazo. |
Maneja errores de SDK de consumidor
El SDK del consumidor envía errores de actualizaciones de viaje a la app para consumidores mediante una devolución de llamada.
de atención. El parámetro de devolución de llamada es un tipo de resultado específico de la plataforma (TripUpdateError
en Android y NSError
en iOS).
Extrae códigos de estado
Por lo general, los errores que se pasan a la devolución de llamada son errores de gRPC, y también puedes extraer información adicional de ellos en forma de un código de estado. Para obtener la lista completa de los códigos de estado, consulta Códigos de estado y su uso en gRPC.
Swift
Se vuelve a llamar a NSError
en 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
Se vuelve a llamar a NSError
en 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;
...
}
}
Cómo interpretar los códigos de estado
Los códigos de estado abarcan dos tipos de errores: errores relacionados con el servidor y la red. errores del cliente.
Errores de servidor y red
Los siguientes códigos de estado son para errores de red o de servidor, y no necesitan tomar medidas para resolverlos. El SDK de consumidor automáticamente se recupera de ellos.
Código de estado | Descripción |
---|---|
ABORTED | El servidor dejó de enviar la respuesta. Por lo general, esto se debe a un en el servidor. |
CANCELADO | El servidor finalizó la respuesta saliente. Esto suele ocurrir cuando la app se envía a segundo plano o cuando hay un cambio de estado en la app de consumidor de . |
/, interrumpido | |
DEADLINE_EXCEEDED | El servidor tardó demasiado en responder. |
NO DISPONIBLE | El servidor no estaba disponible. Por lo general, esto se debe a una red problema. |
Errores de cliente
Los siguientes códigos de estado son para errores de cliente; debes tomar medidas para y resolverlos. El SDK del consumidor continúa reintentando actualizar el viaje hasta que finalizas el recorrido, pero no se recuperará hasta que tomes medidas al respecto.
Código de estado | Descripción |
---|---|
INVALID_ARGUMENT | La app para consumidores especificó un nombre de viaje no válido. El nombre del viaje debe
sigue el formato providers/{provider_id}/trips/{trip_id} .
|
NOT_FOUND | El viaje nunca se creó. |
PERMISSION_DENIED | La app para consumidores no tiene permisos suficientes. Este error ocurre en las siguientes situaciones:
|
RESOURCE_EXHAUSTED | La cuota de recursos está en cero, o la frecuencia del flujo de tráfico supera el límite de velocidad. |
UNAUTHENTICATED | Falló la autenticación de la solicitud debido a un token JWT no válido. Este error ocurre cuando el token JWT se firma sin un ID de viaje o cuando el token JWT venció. |