عند تتبُّع رحلة، يعرض تطبيق المستهلك الموقع الجغرافي للمركبة المناسبة للمستهلك. ولإجراء ذلك، يجب أن يبدأ تطبيقك في تتبُّع رحلة، وأن يعدّل مستوى تقدّم الرحلة، وأن يتوقّف عن تتبُّع الرحلة عند اكتمالها.
يتناول هذا المستند طريقة عمل هذه العملية.
بدء متابعة رحلة
إليك كيفية البدء في متابعة رحلة:
جمع جميع مدخلات المستخدمين، مثل مواقع التسليم والاستلام، من
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 Error. للحصول على تعريفات تفصيلية لرسائل الخطأ وجميع رموز الخطأ، يُرجى الرجوع إلى مستندات أخطاء Google Cloud.
في ما يلي بعض الأخطاء الشائعة التي يمكن أن تحدث أثناء تتبُّع الرحلة:
HTTP | متوسط عائد النقرة | الوصف |
---|---|---|
400 | INVALID_ARGUMENT | حدّد العميل اسم رحلة غير صالح. يجب أن يتّبع اسم الرحلة تنسيق providers/{provider_id}/trips/{trip_id} . يجب أن يكون provider_id هو معرّف مشروع Cloud الذي يملكه مقدّم الخدمة. |
401 | UNAUTHENTICATED | يظهر هذا الخطأ إذا لم تتوفر بيانات اعتماد صالحة للمصادقة. على سبيل المثال، إذا تم التوقيع على رمز JWT المميّز بدون معرّف رحلة أو إذا انتهت صلاحية رمز JWT المميّز. |
403 | PERMISSION_DENIED | يظهر هذا الخطأ إذا لم يكن لدى العميل إذن كافٍ (على سبيل المثال، إذا حاول مستخدم لديه دور مستهلك استدعاء updateTrip)، أو إذا كان رمز JWT غير صالح، أو إذا لم يتم تفعيل واجهة برمجة التطبيقات لمشروع العميل. قد يكون الرمز المميّز JWT غير متوفّر أو تم توقيعه باستخدام معرّف رحلة لا يتطابق مع معرّف الرحلة المطلوب. |
429 | RESOURCE_EXHAUSTED | تبلغ حصة الموارد صفرًا أو يتجاوز معدّل عدد الزيارات الحدّ الأقصى المسموح به. |
503 | UNAVAILABLE | الخدمة غير متاحة. عادةً ما يكون الخادم معطّلاً. |
504 | DEADLINE_EXCEEDED | انتهت المهلة النهائية لتقديم الطلب. لا يحدث هذا الخطأ إلا إذا حدّد المتصل مهلة أقصر من المهلة التلقائية للإجراء (أي أنّ المهلة المطلوبة غير كافية ليتمكّن الخادم من معالجة الطلب) ولم يكتمل الطلب خلال المهلة المحدّدة. |
التعامل مع أخطاء حزمة تطوير البرامج (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;
...
}
}
تفسير رموز الحالة
تتضمّن رموز الحالة نوعَين من الأخطاء: الأخطاء المتعلّقة بالخادم والشبكة، والأخطاء من جهة العميل.
أخطاء الخادم والشبكة
رموز الحالة التالية مخصّصة لأخطاء الشبكة أو الخادم، ولا يلزمك اتّخاذ أي إجراء لحلّها. وتتعافى حزمة تطوير البرامج (SDK) المخصّصة للمستهلك تلقائيًا من هذه الأخطاء.
رمز الحالة | الوصف |
---|---|
تم إلغاؤه | توقّف الخادم عن إرسال الردّ. ويحدث ذلك عادةً بسبب مشكلة في الخادم. |
تم إلغاؤها | أوقف الخادم الاستجابة الصادرة. يحدث ذلك عادةً عندما يتم إرسال التطبيق إلى الخلفية أو عند حدوث تغيير في حالة تطبيق المستهلك. |
تمت مقاطعتها | |
DEADLINE_EXCEEDED | استغرق الخادم وقتًا طويلاً جدًا للاستجابة. |
UNAVAILABLE | كان الخادم غير متاح. ويحدث ذلك عادةً بسبب مشكلة في الشبكة. |
أخطاء العميل
رموز الحالة التالية مخصّصة للأخطاء لجهة العميل، ويجب اتّخاذ إجراء لحلّها. ستواصل حزمة SDK للمستهلك إعادة محاولة تحديث الرحلة إلى أن توقف مشاركة الرحلة، ولكن لن يتم استردادها إلا بعد اتخاذ إجراء.
رمز الحالة | الوصف |
---|---|
INVALID_ARGUMENT | حدّد تطبيق المستهلك اسم رحلة غير صالح. يجب أن يتّبع اسم الرحلة التنسيق providers/{provider_id}/trips/{trip_id} .
|
NOT_FOUND | لم يتم إنشاء الرحلة أبدًا. |
PERMISSION_DENIED | لا يملك تطبيق المستهلك أذونات كافية. يحدث هذا الخطأ في الحالات التالية:
|
RESOURCE_EXHAUSTED | حصة الموارد تساوي صفرًا، أو أنّ معدّل تدفّق الزيارات يتجاوز الحدّ الأقصى للسرعة. |
UNAUTHENTICATED | تعذَّرت مصادقة الطلب بسبب رمز JWT غير صالح. يحدث هذا الخطأ عندما يتم توقيع رمز JWT المميّز بدون رقم تعريف رحلة، أو عندما تنتهي صلاحية رمز JWT المميّز. |