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