وقتی سفری را دنبال میکنید، برنامه مصرفکننده شما مکان خودرو مناسب را به مصرفکننده نشان میدهد. برای انجام این کار، برنامه شما باید دنبال کردن سفر را شروع کند، پیشرفت سفر را بهروز کند، و وقتی سفر تکمیل شد دنبال کردن آن را متوقف کند.
این سند نحوه عملکرد این فرایند را پوشش میدهد.
شروع دنبال کردن سفر
در اینجا نحوه شروع دنبال کردن سفر آمده است:
همه ورودیهای کاربر مثل مکانهای تحویل و دریافت را از
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()
}
آبجکتیو-سی
/*
* 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)
}
آبجکتیو-سی
/*
* 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)
}
آبجکتیو-سی
/*
* MapViewController.m
*/
- (void)viewDidLoad {
[super viewDidLoad];
// Register for trip update events.
[self.currentTripModel registerSubscriber:self];
...
}
مثال توقف شنیدن بهروزرسانیها
مثال زیر نحوه لغو ثبت tripModel
بازخوان را نشان میدهد.
Swift
/*
* MapViewController.swift
*/
deinit {
self.currentTripModel.unregisterSubscriber(self)
}
آبجکتیو-سی
/*
* 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.
}
آبجکتیو-سی
/*
* 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(_:didFailUpdateTripWithError:)،
تماس برگشتی tripModel را دریافت کنید. پیامهای خطا از استاندارد خطای Google Cloud پیروی میکنند. برای مشاهده تعاریف دقیق پیام خطا و همه کدهای خطا، به اسناد خطاهای Google Cloud مراجعه کنید.
در اینجا برخیاز خطاهای رایجی که ممکن است درطول پایش سفر رخ دهد آورده شده است:
| HTTP | RPC | شرح |
|---|---|---|
| ۴۰۰ | INVALID_ARGUMENT | کارخواه نام سفر نامعتبری را مشخص کرده است. نام سفر باید از
قالب providers/{provider_id}/trips/{trip_id} پیروی کند. provider_id باید شناسه پروژه Cloud متعلق به
ارائهدهنده خدمات باشد. |
| 401 | اصالتسنجینشده | اگر اطلاعات اعتباری اصالتسنجی معتبری وجود نداشته باشد، این خطا را دریافت میکنید. برای مثال، اگر نشان JWT بدون شناسه سفر امضا شده باشد یا نشان JWT منقضی شده باشد. |
| 403 | PERMISSION_DENIED | اگر مشتری اجازه کافی نداشته باشد (برای مثال، کاربری با نقش مصرفکننده سعی کند updateTrip را فراخوانی کند)، اگر نشان JWT نامعتبر باشد، یا اگر API برای پروژه مشتری فعال نباشد، این خطا را دریافت میکنید. ممکن است کد JWT وجود نداشته باشد یا کد با شناسه سفری امضا شده باشد که با شناسه سفر درخواستشده مطابقت ندارد. |
| 429 | RESOURCE_EXHAUSTED | سهمیه منبع صفر است یا نرخ ترافیک از حد مجاز فراتر رفته است. |
| ۵۰۳ | دردسترس نیست | سرویس دردسترس نیست. معمولاً سرور ازکار افتاده است. |
| 504 | DEADLINE_EXCEEDED | مهلت درخواست تمام شد. این خطا فقط زمانی رخ میدهد که تماسگیرنده مهلتی را تعیین کند که کوتاهتر از مهلت پیشفرض روش باشد (یعنی مهلت درخواستشده برای پردازش درخواست توسط سرور کافی نباشد) و درخواست در مهلت مقرر تکمیل نشود. |
مدیریت خطاهای «کیت توسعه نرمافزار مصرفکننده»
«کیت توسعه نرمافزار مصرفکننده» خطاهای بهروزرسانی سفر را بااستفاده از سازوکار
بازخوانی به برنامه مصرفکننده ارسال میکند. پارامتر تماس برگشتی نوع برگشتی مختص پلاتفرم است (
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
...
}
}
آبجکتیو-سی
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;
...
}
}
تفسیر کدهای وضعیت
کدهای وضعیت دو نوع خطا را پوشش میدهند: خطاهای مربوط به سرور و شبکه، و خطاهای سمت کارخواه.
خطاهای سرور و شبکه
کدهای وضعیت زیر مربوط به خطاهای شبکه یا سرور هستند و برای حل آنها نیازی به انجام هیچ اقدامی ندارید. «کیت توسعه نرمافزار مصرفکننده» بهطور خودکار از آنها بازیابی میشود.
| رمز وضعیت | شرح |
|---|---|
| لغو شد | سرور ارسال پاسخ را متوقف کرد. این مشکل معمولاً بهدلیل مشکل سرور رخ میدهد. |
| لغو شد | سرور پاسخ خروجی را خاتمه داد. این اتفاق معمولاً زمانی رخ میدهد که
برنامه به پسزمینه ارسال میشود، یا زمانی که وضعیت در برنامه «مصرفکننده» تغییر میکند. |
| قطعشده | |
| DEADLINE_EXCEEDED | پاسخ دادن سرور خیلی طول کشید. |
| دردسترس نیست | سرور دردسترس نبود. این مشکل معمولاً بهدلیل مشکل شبکه رخ میدهد. |
خطاهای کارخواه
کدهای وضعیت زیر مربوط به خطاهای کارخواه است و باید برای رفع آنها اقدام کنید. «کیت توسعه نرمافزار مصرفکننده» تا زمانی که همرسانی سفر را پایان دهید، به تلاش مجدد برای بازآوری سفر ادامه میدهد، اما تا زمانی که اقدامی انجام ندهید، بازیابی نخواهد شد.
| کد وضعیت | شرح |
|---|---|
| INVALID_ARGUMENT | برنامه «مصرفکننده» نام سفر نامعتبری را مشخص کرده است؛ نام سفر باید
از قالب providers/{provider_id}/trips/{trip_id} پیروی کند.
|
| NOT_FOUND | سفر هرگز ایجاد نشده است. |
| PERMISSION_DENIED | برنامه «مصرفکننده» اجازههای کافی ندارد. این خطا زمانی رخ میدهد که:
|
| RESOURCE_EXHAUSTED | سهمیه منبع صفر است یا نرخ جریان ترافیک از حد سرعت فراتر رفته است. |
| اصالتسنجینشده | درخواست بهدلیل نامعتبر بودن نمودار اصالتسنجی ناموفق بود. این خطا زمانی رخ میدهد که نشان JWT بدون شناسه سفر امضا شده باشد، یا زمانی که نشان JWT منقضی شده باشد. |