เมื่อคุณติดตามการเดินทาง แอปสำหรับผู้บริโภคจะแสดงตำแหน่งของ ยานพาหนะที่เหมาะสมต่อผู้บริโภค โดยแอปจะต้องเริ่ม ติดตามการเดินทาง อัปเดตความคืบหน้าของการเดินทาง และหยุดติดตามการเดินทางเมื่อ การเดินทางเสร็จสมบูรณ์
เอกสารนี้จะอธิบายวิธีการทำงานของกระบวนการดังกล่าว
เริ่มติดตามการเดินทาง
วิธีเริ่มติดตามการเดินทางมีดังนี้
- รวบรวมข้อมูลที่ผู้ใช้ป้อนทั้งหมด เช่น สถานที่ส่งและรับ จาก - ViewController
- สร้าง - ViewControllerใหม่เพื่อเริ่มติดตามการเดินทางโดยตรง
ตัวอย่างต่อไปนี้แสดงวิธีเริ่มติดตามการเดินทางทันทีหลังจากโหลดมุมมอง
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];
}
หยุดติดตามการเดินทาง
คุณจะเลิกติดตามการเดินทางเมื่อการเดินทางเสร็จสมบูรณ์หรือถูกยกเลิก ตัวอย่างต่อไปนี้แสดงวิธีหยุดแชร์การเดินทางที่ใช้งานอยู่
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];
}
อัปเดตความคืบหน้าของการเดินทาง
ในระหว่างการเดินทาง คุณจะจัดการความคืบหน้าของการเดินทางได้ดังนี้
- เริ่มฟังข้อมูลอัปเดต ดูตัวอย่างได้ที่ ตัวอย่างการเริ่มฟังการอัปเดต 
- จัดการการอัปเดตการเดินทาง ดูตัวอย่างได้ที่ ตัวอย่างการจัดการข้อมูลอัปเดตการเดินทาง 
เมื่อการเดินทางเสร็จสิ้นหรือถูกยกเลิก ให้หยุดฟังการอัปเดต ดูตัวอย่างได้ที่ตัวอย่างการหยุดฟังการอัปเดต
ตัวอย่างการเริ่มฟังเพื่อรับข้อมูลอัปเดต
ตัวอย่างต่อไปนี้แสดงวิธีลงทะเบียนการเรียกกลับ 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];
  ...
}
ตัวอย่างการหยุดฟังการอัปเดต
ตัวอย่างต่อไปนี้แสดงวิธียกเลิกการลงทะเบียนtripModel
การเรียกกลับ
Swift
/*
 * MapViewController.swift
 */
deinit {
  self.currentTripModel.unregisterSubscriber(self)
}
Objective-C
/*
 * MapViewController.m
 */
- (void)dealloc {
  [self.currentTripModel unregisterSubscriber:self];
  ...
}
ตัวอย่างการจัดการข้อมูลอัปเดตการเดินทาง
ตัวอย่างต่อไปนี้แสดงวิธีใช้GMTCTripModelSubscriber
โปรโตคอลสำหรับการจัดการการเรียกกลับเมื่อมีการอัปเดตสถานะการเดินทาง
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.
}
จัดการข้อผิดพลาดในการเดินทาง
หากคุณสมัครใช้บริการ tripModel และเกิดข้อผิดพลาด คุณจะรับการเรียกกลับ
ของ tripModel ได้โดยการใช้เมธอดตัวแทน
tripModel(_:didFailUpdateTripWithError:) ข้อความแสดงข้อผิดพลาด
เป็นไปตามมาตรฐานข้อผิดพลาดของ Google Cloud โปรดดูคำจำกัดความของข้อความแสดงข้อผิดพลาดโดยละเอียดและรหัสข้อผิดพลาดทั้งหมดในเอกสารประกอบเกี่ยวกับข้อผิดพลาดของ Google Cloud
ข้อผิดพลาดที่พบบ่อยซึ่งอาจเกิดขึ้นระหว่างการตรวจสอบการเดินทางมีดังนี้
| HTTP | RPC | คำอธิบาย | 
|---|---|---|
| 400 | INVALID_ARGUMENT | ไคลเอ็นต์ระบุชื่อการเดินทางไม่ถูกต้อง ชื่อการเดินทางต้องเป็นไปตามรูปแบบ providers/{provider_id}/trips/{trip_id}provider_id ต้องเป็นรหัสของโปรเจ็กต์ระบบคลาวด์ที่เป็นของ
  ผู้ให้บริการ | 
| 401 | UNAUTHENTICATED | คุณจะได้รับข้อผิดพลาดนี้หากไม่มีข้อมูลเข้าสู่ระบบการตรวจสอบสิทธิ์ที่ถูกต้อง เช่น หากโทเค็น JWT ลงนามโดยไม่มีรหัสการเดินทางหรือโทเค็น JWT หมดอายุ | 
| 403 | PERMISSION_DENIED | คุณจะได้รับข้อผิดพลาดนี้หากไคลเอ็นต์มีสิทธิ์ไม่เพียงพอ (เช่น ผู้ใช้ที่มีบทบาทผู้บริโภคพยายามเรียกใช้ updateTrip) หากโทเค็น JWT ไม่ถูกต้อง หรือไม่ได้เปิดใช้ API สำหรับโปรเจ็กต์ไคลเอ็นต์ อาจไม่มีโทเค็น JWT หรือโทเค็นลงนามด้วยรหัสการเดินทางที่ไม่ตรงกับรหัสการเดินทางที่ขอ | 
| 429 | RESOURCE_EXHAUSTED | โควต้าทรัพยากรเป็น 0 หรืออัตราการเข้าชมเกินขีดจำกัด | 
| 503 | UNAVAILABLE | ไม่พร้อมให้บริการ โดยปกติแล้วเซิร์ฟเวอร์จะหยุดทำงาน | 
| 504 | DEADLINE_EXCEEDED | เกินกำหนดเวลาในการส่งคำขอแล้ว ข้อผิดพลาดนี้จะเกิดขึ้นก็ต่อเมื่อผู้โทรตั้งค่า กำหนดเวลาที่สั้นกว่ากำหนดเวลาเริ่มต้นของเมธอด (กล่าวคือ กำหนดเวลาที่ขอไม่เพียงพอให้เซิร์ฟเวอร์ประมวลผลคำขอ) และ คำขอไม่เสร็จสิ้นภายในกำหนดเวลา | 
จัดการข้อผิดพลาดของ Consumer SDK
SDK สำหรับผู้บริโภคจะส่งข้อผิดพลาดในการอัปเดตการเดินทางไปยังแอปสำหรับผู้บริโภคโดยใช้กลไกการเรียกกลับ
 พารามิเตอร์การเรียกกลับคือประเภทการคืนค่าเฉพาะแพลตฟอร์ม (
TripUpdateError
ใน Android และ
NSError
ใน iOS)
ดึงข้อมูลรหัสสถานะ
โดยปกติแล้ว ข้อผิดพลาดที่ส่งไปยังการเรียกกลับจะเป็นข้อผิดพลาดของ gRPC และคุณยังสามารถ ดึงข้อมูลเพิ่มเติมจากข้อผิดพลาดเหล่านั้นในรูปแบบรหัสสถานะได้ด้วย ดูรายการรหัสสถานะทั้งหมดได้ที่รหัสสถานะและการใช้งานใน gRPC
Swift
ระบบจะเรียกใช้ NSError อีกครั้งใน 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
ระบบจะเรียกใช้ NSError อีกครั้งใน 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;
    ...
  }
}
ทำความเข้าใจรหัสสถานะ
รหัสสถานะครอบคลุมข้อผิดพลาด 2 ประเภท ได้แก่ ข้อผิดพลาดเกี่ยวกับเซิร์ฟเวอร์และเครือข่าย และข้อผิดพลาดฝั่งไคลเอ็นต์
ข้อผิดพลาดเกี่ยวกับเซิร์ฟเวอร์และเครือข่าย
รหัสสถานะต่อไปนี้ใช้สำหรับข้อผิดพลาดเกี่ยวกับเครือข่ายหรือเซิร์ฟเวอร์ และคุณไม่จำเป็นต้องดำเนินการใดๆ เพื่อแก้ไข Consumer SDK จะกู้คืนจากข้อผิดพลาดเหล่านี้โดยอัตโนมัติ
| รหัสสถานะ | คำอธิบาย | 
|---|---|
| ถูกยกเลิก | เซิร์ฟเวอร์หยุดส่งการตอบกลับ โดยปกติแล้ว ปัญหานี้เกิดจาก ปัญหาเกี่ยวกับเซิร์ฟเวอร์ | 
| ยกเลิกแล้ว | เซิร์ฟเวอร์สิ้นสุดการตอบกลับขาออก โดยปกติแล้ว
      เหตุการณ์นี้จะเกิดขึ้นเมื่อ แอปถูกส่งไปทำงานเบื้องหลัง หรือเมื่อมีการเปลี่ยนแปลงสถานะใน แอปสำหรับผู้บริโภค | 
| ถูกขัดจังหวะ | |
| DEADLINE_EXCEEDED | เซิร์ฟเวอร์ใช้เวลาตอบสนองนานเกินไป | 
| UNAVAILABLE | เซิร์ฟเวอร์ไม่พร้อมใช้งาน โดยปกติแล้ว ปัญหานี้เกิดจากปัญหาเกี่ยวกับเครือข่าย | 
ข้อผิดพลาดของไคลเอ็นต์
รหัสสถานะต่อไปนี้เป็นข้อผิดพลาดของไคลเอ็นต์ และคุณต้องดำเนินการเพื่อ แก้ไข SDK สำหรับผู้บริโภคจะลองรีเฟรชการเดินทางต่อไปจนกว่าคุณจะ สิ้นสุดการแชร์การเดินทาง แต่จะไม่กู้คืนจนกว่าคุณจะดำเนินการ
| รหัสสถานะ | คำอธิบาย | 
|---|---|
| INVALID_ARGUMENT | แอปสำหรับผู้บริโภคระบุชื่อการเดินทางที่ไม่ถูกต้อง ชื่อการเดินทางต้องเป็นไปตามรูปแบบ providers/{provider_id}/trips/{trip_id} | 
| NOT_FOUND | ไม่มีการสร้างการเดินทาง | 
| PERMISSION_DENIED | แอปสำหรับผู้บริโภคมีสิทธิ์ไม่เพียงพอ ข้อผิดพลาดนี้จะเกิดขึ้นเมื่อ 
 | 
| RESOURCE_EXHAUSTED | โควต้าทรัพยากรเป็น 0 หรืออัตราการไหลของการเข้าชมเกิน ขีดจำกัดความเร็ว | 
| UNAUTHENTICATED | คำขอตรวจสอบสิทธิ์ไม่สำเร็จเนื่องจากโทเค็น JWT ไม่ถูกต้อง ข้อผิดพลาดนี้ เกิดขึ้นเมื่อมีการลงนามโทเค็น JWT โดยไม่มีรหัสการเดินทาง หรือ เมื่อโทเค็น JWT หมดอายุ |