بدء استخدام Driver SDK لنظام التشغيل iOS

يمكنك استخدام Driver SDK لتوفير تنقل وتتبّع محسّنين لتطبيق تقدّمك في الرحلات والطلبات. توفر Driver SDK تحديثات لموقع المركبات وتحديثات المهام لحلول Fleet Engine المتعلقة بالرحلات والتسليمات عند الطلب.

تعمل حزم SDK للسائق على إطلاع خدمات Fleet Engine والخدمات المخصّصة على موقع المركبة وحالتها. على سبيل المثال، قد تكون المركبة ONLINE أو OFFLINE، ويتغير الموقع الجغرافي للمركبة مع تقدّم الرحلة.

الحد الأدنى من متطلبات النظام

  • يجب أن يعمل الجهاز الجوّال بنظام التشغيل iOS 13 أو بإصدار أحدث.
  • Xcode الإصدار 14 أو إصدار أحدث.
  • المتطلبات الأساسية

    يفترض هذا الدليل أن تطبيقك ينفّذ بالفعل حزمة SDK للتنقل وأنه تم إعداد الواجهة الخلفية لـ Fleet Engine وتوفّرها. ومع ذلك، يوفر الرمز النموذجي نموذجًا عن كيفية إعداد حزمة SDK للتنقل.

    يجب أيضًا تفعيل حزمة تطوير البرامج (SDK) لـ "خرائط Google" لنظام التشغيل iOS في مشروع Google Cloud والحصول على مفتاح واجهة برمجة التطبيقات.

    إعدادات المشروع

    يمكنك إعداد حزمة تطوير البرامج (SDK) للسائق باستخدام CocoaPods.

    استخدام CocoaPods

    لإعداد "حزمة تطوير البرامج (SDK) لبرنامج التشغيل" باستخدام CocoaPods، ستحتاج إلى العناصر التالية:

    • أداة CocoaPods: لتثبيت هذه الأداة، افتح الوحدة الطرفية وشغِّل الأمر التالي. shell sudo gem install cocoapods يمكنك الرجوع إلى دليل بدء استخدام CocoaPods للحصول على مزيد من التفاصيل.
    1. أنشئ ملف Podfile لـ Driver SDK واستخدمه لتثبيت واجهة برمجة التطبيقات وتبعياتها: أنشئ ملفًا يسمى Podfile في دليل مشروعك. يحدد هذا الملف تبعيات مشروعك. قم بتحرير Podfile وإضافة التبعيات الخاصة بك. فيما يلي مثال يتضمن التبعيات:

      source "https://github.com/CocoaPods/Specs.git"
      
      target 'YOUR_APPLICATION_TARGET_NAME_HERE' do
        pod 'GoogleRidesharingDriver'
      end
      

      في ما يلي مثال يتضمن لوحات الإصدار الأولي والإصدار التجريبي لحزمة تطوير البرامج Driver SDK كتبعيات:

      source "https://cpdc-eap.googlesource.com/ridesharing-driver-sdk.git"
      source "https://github.com/CocoaPods/Specs.git"
      
      target 'YOUR_APPLICATION_TARGET_NAME_HERE' do
        pod 'GoogleRidesharingDriver'
      end
      
    2. احفظ Podfile. افتح وحدة طرفية وانتقل إلى الدليل الذي يحتوي على Podfile:

      cd <path-to-project>
      
    3. شغّل أمر pod install. سيؤدي هذا إلى تثبيت واجهات برمجة التطبيقات المحددة في Podfile، بالإضافة إلى أي تبعيات قد تكون لديهم.

      pod install
      
    4. أغلق Xcode، ثم افتح (انقر نقرًا مزدوجًا) ملف .xcworkspace لمشروعك لتشغيل Xcode. من هذا الوقت فصاعدًا، يجب عليك استخدام ملف .xcworkspace لفتح المشروع.

    إصدارات الإصدار الأولي/التجريبي من حزمة تطوير البرامج (SDK)

    لإعداد الإصدار الأولي أو الإصدار التجريبي من تطبيق Driver SDK لنظام التشغيل iOS، ستحتاج إلى العناصر التالية:

    • أداة CocoaPods: لتثبيت هذه الأداة، افتح الوحدة الطرفية وشغِّل الأمر التالي.

      sudo gem install cocoapods
      

      للاطّلاع على مزيد من التفاصيل، يمكنك الرجوع إلى دليل بدء استخدام CocoaPods.

    • حساب التطوير الخاص بك في قائمة الوصول على Google. لا يعتبر مستودع مجموعة الإعلانات المتسلسلة الخاص بالإصدارات ألفا والتجريبية من حزمة SDK مصدرًا عامًا. للوصول إلى هذه الإصدارات، اتصل بمهندس العملاء في Google. ويضيف المهندس حساب التطوير الخاص بك إلى قائمة الوصول ثم يضبط ملف تعريف ارتباط للمصادقة.

    بعد إدراج مشروعك في قائمة الوصول، يمكنك الوصول إلى المجموعة.

    1. أنشئ ملف Podfile لحزمة Delivery SDK لنظام التشغيل iOS واستخدمه لتثبيت واجهة برمجة التطبيقات وتبعياتها: أنشئ ملفًا باسم Podfile في دليل مشروعك. يحدد هذا الملف تبعيات مشروعك. قم بتحرير Podfile وإضافة التبعيات الخاصة بك. فيما يلي مثال يتضمن التبعيات:

      source "https://cpdc-eap.googlesource.com/ridesharing-driver-sdk.git"
      source "https://github.com/CocoaPods/Specs.git"
      
      target 'YOUR_APPLICATION_TARGET_NAME_HERE' do
        pod 'GoogleRidesharingDriver'
      end
      
    2. احفظ Podfile. افتح وحدة طرفية وانتقل إلى الدليل الذي يحتوي على Podfile:

      cd <path-to-project>
      
    3. شغّل أمر pod install. يقوم هذا الأمر بتثبيت واجهات برمجة التطبيقات المحددة في Podfile، بالإضافة إلى أي تبعيات قد تكون لديهم.

      pod install
      
    4. أغلق Xcode، ثم افتح (انقر نقرًا مزدوجًا) ملف .xcworkspace لمشروعك لتشغيل Xcode. من هذا الوقت فصاعدًا، يجب عليك استخدام ملف .xcworkspace لفتح المشروع.

    تنفيذ التفويض والمصادقة

    عندما ينشئ تطبيق Driver تحديثات ويرسلها إلى خلفية Fleet Engine، يجب أن تتضمّن الطلبات رموز دخول صالحة. لمصادقة هذه الطلبات ومصادقتها، تستدعي حزمة تطوير البرامج Driver SDK العنصر وفقًا للبروتوكول GMTDAuthorization. يكون الكائن مسؤولاً عن توفير رمز الدخول المطلوب.

    بصفتك مطوِّر التطبيق، بإمكانك اختيار كيفية إنشاء الرموز المميّزة. يجب أن يوفر التنفيذ لديك إمكانية القيام بما يلي:

    • يمكنك جلب رمز دخول، ربما بتنسيق JSON، من خادم HTTPS.
    • تحليل الرمز المميّز وتخزينه مؤقتًا
    • أعِد تحميل الرمز المميّز عند انتهاء صلاحيته.

    لمعرفة تفاصيل الرموز المميّزة التي يتوقعها خادم Fleet Engine، يُرجى الاطّلاع على إنشاء رمز JSON المميّز للويب (JWT) للتفويض.

    رقم تعريف مقدِّم الخدمة هو نفسه رقم تعريف مشروع Google Cloud. يمكنك الاطّلاع على دليل البدء السريع حول Fleet Engine للحصول على مزيد من المعلومات.

    ينفِّذ المثال التالي موفِّر رمز دخول:

    Swift

    import GoogleRidesharingDriver
    
    private let providerURL = "INSERT_YOUR_TOKEN_PROVIDER_URL"
    
    class SampleAccessTokenProvider: NSObject, GMTDAuthorization {
      private struct AuthToken {
        // The cached vehicle token.
        let token: String
        // Keep track of when the token expires for caching.
        let expiration: TimeInterval
        // Keep track of the vehicle ID the cached token is for.
        let vehicleID: String
      }
    
      enum AccessTokenError: Error {
        case missingAuthorizationContext
        case missingData
      }
    
      private var authToken: AuthToken?
    
      func fetchToken(
        with authorizationContext: GMTDAuthorizationContext?,
        completion: @escaping GMTDAuthTokenFetchCompletionHandler
      ) {
        // Get the vehicle ID from the authorizationContext. This is set by the Driver SDK.
        guard let authorizationContext = authorizationContext else {
          completion(nil, AccessTokenError.missingAuthorizationContext)
          return
        }
        let vehicleID = authorizationContext.vehicleID
    
        // If appropriate, use the cached token.
        if let authToken = authToken,
          authToken.expiration > Date.now.timeIntervalSince1970 && authToken.vehicleID == vehicleID
        {
          completion(authToken.token, nil)
          return
        }
    
        // Otherwise, try to fetch a new token from your server.
        let request = URLRequest(url: URL(string: providerURL))
        let task = URLSession.shared.dataTask(with: request) { [weak self] data, _, error in
          guard let strongSelf = self else { return }
          guard error == nil else {
            completion(nil, error)
            return
          }
    
          // Replace the following key values with the appropriate keys based on your
          // server's expected response.
          let vehicleTokenKey = "VEHICLE_TOKEN_KEY"
          let tokenExpirationKey = "TOKEN_EXPIRATION"
          guard let data = data,
            let fetchData = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
            let token = fetchData[vehicleTokenKey] as? String,
            let expiration = fetchData[tokenExpirationKey] as? Double
          else {
            completion(nil, AccessTokenError.missingData)
            return
          }
    
          strongSelf.authToken = AuthToken(
            token: token, expiration: expiration, vehicleID: vehicleID)
          completion(token, nil)
        }
        task.resume()
      }
    }
    

    Objective-C

    #import "SampleAccessTokenProvider.h"
    #import <GoogleRidesharingDriver/GoogleRidesharingDriver.h>
    
    // SampleAccessTokenProvider.h
    @interface SampleAccessTokenProvider : NSObject<GMTDAuthorization>
    @end
    
    static NSString *const PROVIDER_URL = @"INSERT_YOUR_TOKEN_PROVIDER_URL";
    
    // SampleAccessTokenProvider.m
    @implementation SampleAccessTokenProvider{
      // The cached vehicle token.
      NSString *_cachedVehicleToken;
      // Keep track of the vehicle ID the cached token is for.
      NSString *_lastKnownVehicleID;
      // Keep track of when tokens expire for caching.
      NSTimeInterval _tokenExpiration;
    }
    
    - (void)fetchTokenWithContext:(nullable GMTDAuthorizationContext *)authorizationContext
                       completion:(nonnull GMTDAuthTokenFetchCompletionHandler)completion {
      // Get the vehicle ID from the authorizationContext. This is set by the Driver SDK.
      NSString *vehicleID = authorizationContext.vehicleID;
      if (!vehicleID) {
        NSAssert(NO, @"Vehicle ID is missing from authorizationContext.");
        return;
      }
    
      // Clear cached vehicle token if vehicle ID has changed.
      if (![_lastKnownVehicleID isEqual:vehicleID]) {
        _tokenExpiration = 0.0;
        _cachedVehicleToken = nil;
      }
      _lastKnownVehicleID = vehicleID;
    
      // Clear cached vehicletoken if it has expired.
      if ([[NSDate date] timeIntervalSince1970] > _tokenExpiration) {
        _cachedVehicleToken = nil;
      }
    
      // If appropriate, use the cached token.
      if (_cachedVehicleToken) {
        completion(_cachedVehicleToken, nil);
        return;
      }
      // Otherwise, try to fetch a new token from your server.
      NSURL *requestURL = [NSURL URLWithString:PROVIDER_URL];
      NSMutableURLRequest *request =
          [[NSMutableURLRequest alloc] initWithURL:requestURL];
      request.HTTPMethod = @"GET";
      // Replace the following key values with the appropriate keys based on your
      // server's expected response.
      NSString *vehicleTokenKey = @"VEHICLE_TOKEN_KEY";
      NSString *tokenExpirationKey = @"TOKEN_EXPIRATION";
      __weak typeof(self) weakSelf = self;
      void (^handler)(NSData *_Nullable data, NSURLResponse *_Nullable response,
                      NSError *_Nullable error) =
          ^(NSData *_Nullable data, NSURLResponse *_Nullable response, NSError *_Nullable error) {
            typeof(self) strongSelf = weakSelf;
            if (error) {
              completion(nil, error);
              return;
            }
    
            NSError *JSONError;
            NSMutableDictionary *JSONResponse =
                [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&JSONError];
    
            if (JSONError) {
              completion(nil, JSONError);
              return;
            } else {
              // Sample code only. No validation logic.
              id expirationData = JSONResponse[tokenExpirationKey];
              if ([expirationData isKindOfClass:[NSNumber class]]) {
                NSTimeInterval expirationTime = ((NSNumber *)expirationData).doubleValue;
                strongSelf->_tokenExpiration = [[NSDate date] timeIntervalSince1970] + expirationTime;
              }
              strongSelf->_cachedVehicleToken = JSONResponse[vehicleTokenKey];
              completion(JSONResponse[vehicleTokenKey], nil);
            }
          };
      NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
      NSURLSession *mainQueueURLSession =
          [NSURLSession sessionWithConfiguration:config delegate:nil
                                   delegateQueue:[NSOperationQueue mainQueue]];
      NSURLSessionDataTask *task = [mainQueueURLSession dataTaskWithRequest:request completionHandler:handler];
      [task resume];
    }
    
    @end
    

    إنشاء مثيل RidesharingDriverAPI

    للحصول على مثيل GMTDVehicleReporter، عليك أولاً إنشاء مثيل GMTDRidesharingDriverAPI باستخدام providerID وvehicleID وdriverContext وaccessTokenProvider. يكون معرف مقدم الخدمة هو نفسه رقم تعريف مشروع Google Cloud. ويمكنك الوصول إلى مثيل GMTDVehicleReporter من واجهة برمجة تطبيقات برنامج التشغيل مباشرةً.

    ينشئ المثال التالي مثيل GMTDRidesharingDriverAPI:

    Swift

    import GoogleRidesharingDriver
    
    private let providerID = "INSERT_YOUR_PROVIDER_ID"
    
    class SampleViewController: UIViewController {
      private let mapView: GMSMapView
    
      override func viewDidLoad() {
        super.viewDidLoad()
    
        let vehicleID = "INSERT_CREATED_VEHICLE_ID"
        let accessTokenProvider = SampleAccessTokenProvider()
        let driverContext = GMTDDriverContext(
          accessTokenProvider: accessTokenProvider,
          providerID: providerID,
          vehicleID: vehicleID,
          navigator: mapView.navigator)
        let ridesharingDriverAPI = GMTDRidesharingDriverAPI(driverContext: driverContext)
      }
    }
    

    Objective-C

    #import "SampleViewController.h"
    #import "SampleAccessTokenProvider.h"
    #import <GoogleRidesharingDriver/GoogleRidesharingDriver.h>
    
    static NSString *const PROVIDER_ID = @"INSERT_YOUR_PROVIDER_ID";
    
    @implementation SampleViewController {
      GMSMapView *_mapView;
    }
    
    - (void)viewDidLoad {
      NSString *vehicleID = @"INSERT_CREATED_VEHICLE_ID";
      SampleAccessTokenProvider *accessTokenProvider =
                                    [[SampleAccessTokenProvider alloc] init];
      GMTDDriverContext *driverContext =
        [[GMTDDriverContext alloc] initWithAccessTokenProvider:accessTokenProvider
                                                    providerID:PROVIDER_ID
                                                     vehicleID:vehicleID
                                                     navigator:_mapView.navigator];
    
      GMTDRidesharingDriverAPI *ridesharingDriverAPI = [[GMTDRidesharingDriverAPI alloc] initWithDriverContext:driverContext];
    }
    

    الاستماع بشكل اختياري إلى فعاليات vehicleReporter

    يعدّل GMTDVehicleReporter المركبة بشكل دوري عندما يكون locationTrackingEnabled هو true. وللاستجابة لهذه التحديثات الدورية، يمكن لأي عنصر الاشتراك في أحداث GMTDVehicleReporter من خلال التوافق مع بروتوكول GMTDVehicleReporterListener.

    يمكنك معالجة الأحداث التالية:

    • vehicleReporter(_:didSucceed:)

      يتم إبلاغ تطبيق Driver بأنّ خدمات الخلفية قد تلقّت بنجاح موقع السيارة وتعديل الحالة لها.

    • vehicleReporter(_:didFail:withError:)

      يتم إبلاغ المستمع بأنّه تعذّر تعديل المركبة. ما دامت ميزة "تتبُّع الموقع الجغرافي" مفعّلة، ستواصل GMTDVehicleReporter إرسال أحدث البيانات إلى الواجهة الخلفية لـ Fleet Engine.

    يتعامل المثال التالي مع هذه الأحداث:

    Swift

    import GoogleRidesharingDriver
    
    private let providerID = "INSERT_YOUR_PROVIDER_ID"
    
    class SampleViewController: UIViewController, GMTDVehicleReporterListener {
      private let mapView: GMSMapView
    
      override func viewDidLoad() {
        // Assumes you have implemented the sample code up to this step.
        ridesharingDriverAPI.vehicleReporter.add(self)
      }
    
      func vehicleReporter(_ vehicleReporter: GMTDVehicleReporter, didSucceed vehicleUpdate: GMTDVehicleUpdate) {
        // Handle update succeeded.
      }
    
      func vehicleReporter(_ vehicleReporter: GMTDVehicleReporter, didFail vehicleUpdate: GMTDVehicleUpdate, withError error: Error) {
        // Handle update failed.
      }
    }
    

    Objective-C

    /*
     * SampleViewController.h
     */
    @interface SampleViewController : UIViewController<GMTDVehicleReporterListener>
    @end
    
    /*
     * SampleViewController.m
     */
    #import "SampleViewController.h"
    #import "SampleAccessTokenProvider.h"
    #import <GoogleRidesharingDriver/GoogleRidesharingDriver.h>
    
    static NSString *const PROVIDER_ID = @"INSERT_YOUR_PROVIDER_ID";
    
    @implementation SampleViewController {
      GMSMapView *_mapView;
    }
    
    - (void)viewDidLoad {
      // Assumes you have implemented the sample code up to this step.
      [ridesharingDriverAPI.vehicleReporter addListener:self];
    }
    
    - (void)vehicleReporter:(GMTDVehicleReporter *)vehicleReporter didSucceedVehicleUpdate:(GMTDVehicleUpdate *)vehicleUpdate {
      // Handle update succeeded.
    }
    
    - (void)vehicleReporter:(GMTDVehicleReporter *)vehicleReporter didFailVehicleUpdate:(GMTDVehicleUpdate *)vehicleUpdate withError:(NSError *)error {
      // Handle update failed.
    }
    
    @end
    

    إضافة GMTDVehicleReporter كمستمع إلى GMSRoadSnappedLocationProvider

    لتوفير تحديثات الموقع الجغرافي لـ Driver SDK، يجب ضبط GMTDVehicleReporter ليكون مستمعًا لـ GMSRoadSnappedLocationProvider.

    Swift

    import GoogleRidesharingDriver
    
    private let providerID = "INSERT_YOUR_PROVIDER_ID"
    
    class SampleViewController: UIViewController, GMTDVehicleReporterListener {
      private let mapView: GMSMapView
    
      override func viewDidLoad() {
        // Assumes you have implemented the sample code up to this step.
        if let roadSnappedLocationProvider = mapView.roadSnappedLocationProvider {
          roadSnappedLocationProvider.add(ridesharingDriverAPI.vehicleReporter)
          roadSnappedLocationProvider.startUpdatingLocation()
        }
      }
    }
    

    Objective-C

    /*
     * SampleViewController.h
     */
    @interface SampleViewController : UIViewController<GMTDVehicleReporterListener>
    @end
    
    /*
     * SampleViewController.m
     */
    #import "SampleViewController.h"
    #import "SampleAccessTokenProvider.h"
    #import <GoogleRidesharingDriver/GoogleRidesharingDriver.h>
    
    static NSString *const PROVIDER_ID = @"INSERT_YOUR_PROVIDER_ID";
    
    @implementation SampleViewController {
      GMSMapView *_mapView;
    }
    
    - (void)viewDidLoad {
      // Assumes you have implemented the sample code up to this step.
      [_mapView.roadSnappedLocationProvider addListener:ridesharingDriverAPI.vehicleReporter];
      [_mapView.roadSnappedLocationProvider startUpdatingLocation];
    }
    
    @end
    

    تفعيل تتبع الموقع الجغرافي

    لتفعيل تتبع الموقع الجغرافي، يمكن لتطبيقك ضبط locationTrackingEnabled على true في GMTDVehicleReporter. يرسل تطبيق "GMTDVehicleReporter" تلقائيًا تعديلات الموقع الجغرافي. بعد مطابقة الخدمات وتخصيص المركبة لرحلة، يرسل GMTDVehicleReporter تعديلات على المسار تلقائيًا عندما يكون GMSNavigator في وضع التنقّل (عند ضبط وجهة عبر setDestinations).

    سيكون المسار الذي تم تعيينه أثناء تحديث الرحلة هو نفس المسار الذي ينتقل إليه السائق أثناء جلسة التنقل. وبالتالي، لكي تعمل ميزة "مشاركة الرحلة" بشكل صحيح، يجب أن تتطابق نقطة الطريق التي تم ضبطها من خلال setDestinations مع الوجهة المحددة في الواجهة الخلفية لـ Fleet Engine.

    إذا تم ضبط locationTrackingEnabled على true، يتم إرسال تحديثات الرحلات والمركبات إلى الواجهة الخلفية لـ Fleet Engine على فترات منتظمة استنادًا إلى القيمة المضبوطة على locationUpdateInterval. إذا تم ضبط locationTrackingEnabled على false، ستتوقف التحديثات ويتم إرسال طلب نهائي لتحديث المركبة إلى الواجهة الخلفية لـ Fleet Engine لضبط حالة المركبة على GMTDVehicleState.offline. راجِع updateVehicleState لمعرفة الاعتبارات الخاصة بشأن التعامل مع حالات التعذُّر عند ضبط locationTrackingEnabled على false.

    يُفعِّل المثال التالي تتبع الموقع الجغرافي:

    Swift

    import GoogleRidesharingDriver
    
    private let providerID = "INSERT_YOUR_PROVIDER_ID"
    
    class SampleViewController: UIViewController, GMTDVehicleReporterListener {
      private let mapView: GMSMapView
    
      override func viewDidLoad() {
        // Assumes you have implemented the sample code up to this step.
        ridesharingDriverAPI.vehicleReporter.locationTrackingEnabled = true
      }
    }
    

    Objective-C

    /*
     * SampleViewController.m
     */
    #import "SampleViewController.h"
    #import "SampleAccessTokenProvider.h"
    #import <GoogleRidesharingDriver/GoogleRidesharingDriver.h>
    
    static NSString *const PROVIDER_ID = @"INSERT_YOUR_PROVIDER_ID";
    
    @implementation SampleViewController {
      GMSMapView *_mapView;
    }
    
    - (void)viewDidLoad {
      // Assumes you have implemented the sample code up to this step.
      ridesharingDriverAPI.vehicleReporter.locationTrackingEnabled = YES;
    }
    
    @end
    

    تبلغ الفترة التلقائية لإعداد التقارير 10 ثوانٍ، ولكن يمكن تغيير الفاصل الزمني لإعداد التقارير باستخدام locationUpdateInterval. يبلغ الحد الأدنى للفاصل الزمني للتحديث المتوافق 5 ثوانٍ. الحد الأقصى لمدة التحديث المتوافقة هو 60 ثانية. قد تؤدي التحديثات المتكررة إلى إبطاء الطلبات والأخطاء.

    تعديل حالة المركبة

    يوضّح المثال التالي كيفية ضبط حالة المركبة على ONLINE. يمكنك الاطّلاع على updateVehicleState لمعرفة التفاصيل.

    Swift

    import GoogleRidesharingDriver
    
    private let providerID = "INSERT_YOUR_PROVIDER_ID"
    
    class SampleViewController: UIViewController, GMTDVehicleReporterListener {
      private let mapView: GMSMapView
    
      override func viewDidLoad() {
        // Assumes you have implemented the sample code up to this step.
        ridesharingDriverAPI.vehicleReporter.update(.online)
      }
    }
    

    Objective-C

    #import "SampleViewController.h"
    #import "SampleAccessTokenProvider.h"
    #import <GoogleRidesharingDriver/GoogleRidesharingDriver.h>
    
    static NSString *const PROVIDER_ID = @"INSERT_YOUR_PROVIDER_ID";
    
    @implementation SampleViewController {
      GMSMapView *_mapView;
    }
    
    - (void)viewDidLoad {
      // Assumes you have implemented the sample code up to this step.
      [ridesharingDriverAPI.vehicleReporter
                                       updateVehicleState:GMTDVehicleStateOnline];
    }
    
    @end
    

    يمكن أن يحدث الخطأ update_mask عندما يكون القناع فارغًا، ويحدث عادةً لأول تحديث بعد بدء التشغيل. يوضح المثال التالي كيفية التعامل مع هذا الخطأ:

    Swift

    import GoogleRidesharingDriver
    
    class VehicleReporterListener: NSObject, GMTDVehicleReporterListener {
      func vehicleReporter(
        _ vehicleReporter: GMTDVehicleReporter,
        didFail vehicleUpdate: GMTDVehicleUpdate,
        withError error: Error
      ) {
        let fullError = error as NSError
        if let innerError = fullError.userInfo[NSUnderlyingErrorKey] as? NSError {
          let innerFullError = innerError as NSError
          if innerFullError.localizedDescription.contains("update_mask cannot be empty") {
            emptyMaskUpdates += 1
            return
          }
        }
        failedUpdates += 1
      }
    
      override init() {
        emptyMaskUpdates = 0
        failedUpdates = 0
      }
    }
    
    

    Objective-C

    #import "VehicleReporterListener.h"
    #import <GoogleRidesharingDriver/GoogleRidesharingDriver.h>
    
    @implementation VehicleReporterListener {
      NSInteger emptyMaskUpdates = 0;
      NSInteger failedUpdates = 0;
    }
    
    - (void)vehicleReporter:(GMTDVehicleReporter *)vehicleReporter
       didFailVehicleUpdate:(GMTDVehicleUpdate *)vehicleUpdate
                  withError:(NSError *)error {
      for (NSError *underlyingError in error.underlyingErrors) {
        if ([underlyingError.localizedDescription containsString:@"update_mask cannot be empty"]) {
          emptyMaskUpdates += 1;
          return;
        }
      }
      failedUpdates += 1
    }
    
    @end
    

    إيقاف تحديثات الموقع الجغرافي وجعل المركبة غير متصلة بالإنترنت

    يمكن لتطبيقك إيقاف التحديثات وتحويل المركبة إلى وضع عدم الاتصال. على سبيل المثال، عند انتهاء دوام السائق، يمكن لتطبيقك ضبط locationTrackingEnabled على false. يؤدي إيقاف التحديثات أيضًا إلى ضبط حالة المركبة على OFFLINE في الواجهة الخلفية لـ Fleet Engine.

    Swift

    vehicleReporter.locationTrackingEnabled = false
    

    Objective-C

    _vehicleReporter.locationTrackingEnabled = NO;