כשעוקבים אחרי נסיעה, מיקום הרכב הרלוונטי מוצג לצרכן באפליקציה לצרכן. כדי לעשות את זה, האפליקציה צריכה להתחיל לעקוב אחרי נסיעה, לעדכן את ההתקדמות בנסיעה ולהפסיק לעקוב אחרי נסיעה כשהיא מסתיימת.
במאמר הזה מוסבר איך התהליך הזה עובד.
התחלת מעקב אחרי נסיעה
כך מתחילים לעקוב אחרי נסיעה:
אוספים את כל קלט המשתמש, כמו מיקומי מסירה ואיסוף, מתוך
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
ומתרחשת שגיאה, תוכלו לקבל את הקריאה החוזרת (callback) של 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 לא תקין או אם ה-API לא מופעל בפרויקט הלקוח. יכול להיות שאסימון ה-JWT חסר או שהאסימון חתום עם מזהה נסיעה שלא תואם למזהה הנסיעה המבוקש. |
429 | RESOURCE_EXHAUSTED | מכסת המשאבים היא אפס או שקצב התנועה חורג מהמגבלה. |
503 | UNAVAILABLE | השירות לא זמין. בדרך כלל השרת מושבת. |
504 | DEADLINE_EXCEEDED | המועד האחרון לשליחת הבקשה חלף. השגיאה הזו מתרחשת רק אם המתקשר מגדיר מועד אחרון שהוא קצר יותר מהמועד האחרון שמוגדר כברירת מחדל לשיטה (כלומר, המועד האחרון שנדרש לא מספיק לשרת כדי לעבד את הבקשה), והבקשה לא הסתיימה לפני המועד האחרון. |
טיפול בשגיאות ב-Consumer SDK
ערכת Consumer SDK שולחת שגיאות בעדכוני נסיעה לאפליקציית הצרכן באמצעות מנגנון של קריאה חוזרת (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 לצרכנים מתאושש מהם באופן אוטומטי.
קוד סטטוס | תיאור |
---|---|
הופסק | השרת הפסיק לשלוח את התגובה. בדרך כלל, הסיבה לכך היא בעיה בשרת. |
בוטלה | השרת הפסיק את התגובה היוצאת. זה קורה בדרך כלל כשהאפליקציה מועברת לרקע, או כשמתרחש שינוי במצב באפליקציית הצרכן. |
הופסקה | |
DEADLINE_EXCEEDED | לשרת לקח יותר מדי זמן להגיב. |
UNAVAILABLE | השרת לא היה זמין. הסיבה לכך היא בדרך כלל בעיה ברשת. |
שגיאות בצד הלקוח
קודי הסטטוס הבאים הם שגיאות בצד הלקוח, וצריך לבצע פעולה כדי לפתור אותן. ערכת ה-SDK לצרכנים ממשיכה לנסות לרענן את הנסיעה עד שמפסיקים את שיתוף הנסיעה, אבל היא לא תפעל שוב עד שתבצעו פעולה.
קוד סטטוס | תיאור |
---|---|
INVALID_ARGUMENT | אפליקציית הצרכן ציינה שם נסיעה לא חוקי. שם הנסיעה צריך להיות בפורמט providers/{provider_id}/trips/{trip_id} .
|
NOT_FOUND | הנסיעה אף פעם לא נוצרה. |
PERMISSION_DENIED | לאפליקציית הצרכן אין מספיק הרשאות. השגיאה הזו מתרחשת במקרים הבאים:
|
RESOURCE_EXHAUSTED | מכסת המשאבים היא אפס, או שקצב זרימת התנועה חורג ממגבלת המהירות. |
לא מאומת | האימות של הבקשה נכשל בגלל טוקן JWT לא תקין. השגיאה הזו מתרחשת אם אסימון ה-JWT נחתם ללא מזהה נסיעה, או אם פג תוקף אסימון ה-JWT. |