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

يمكنك استخدام Driver SDK لتحسين التنقّل والتتبُّع في تطبيق "مستوى تقدُّم الطلب والتنقل". توفر Driver SDK تحديثات لموقع المركبة والمهام إلى محرك أسطول حلول الرحلات والتسليمات عند الطلب.

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

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

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

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

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

    تكوين المشروع

    مدير حِزم Swift

    يمكن تثبيت Driver SDK من خلال Swift Package Manager. لإضافة حزمة SDK، تأكَّد من إزالة أي تبعيات حالية لـ Driver SDK.

    لإضافة حزمة SDK إلى مشروع جديد أو حالي، يُرجى اتّباع الخطوات التالية:

    1. افتح Xcode project أو workspace، ثم انتقِل إلى ملف > إضافة تبعيات الحزمة.
    2. أدخِل https://github.com/googlemaps/ios-driver-sdk كعنوان URL، واضغط على Enter لسحب الحزمة، ثم انقر على "Add Package".
    3. لتثبيت version محدّد، اضبط الحقل قاعدة التبعية على أحد الخيارات المستندة إلى الإصدار. بالنسبة إلى المشاريع الجديدة، ننصحك بتحديد أحدث إصدار واستخدام الخيار "Exact Version". بعد الانتهاء من التعديل، انقر على "Add Package" (إضافة حزمة).
    4. من نافذة اختيار منتجات الحزم، تأكَّد من إضافة GoogleRidesharingDriver إلى هدف main المحدّد. بعد الانتهاء من التعديل، انقر على "Add Package" (إضافة حزمة).
    5. للتحقّق من التثبيت، انتقِل إلى جزء General المستهدَف. في إطارات الأطر والمكتبات والمحتوى المضمَّن، من المفترض أن تظهر لك الحِزم المثبَّتة. يمكنك أيضًا عرض القسم "تبعيات الحزمة" في "Project Navigator" للتحقق من الحزمة وإصدارها.

    لتعديل package لمشروع حالي، اتّبِع الخطوات التالية:

    1. من Xcode، انتقل إلى "ملف > الحزم > التحديث إلى أحدث إصدارات الحزمة".
    2. للتحقّق من التثبيت، انتقِل إلى قسم تبعيات الحزمة في Project Navigator للتحقّق من الحزمة وإصدارها.

    لإزالة تبعيات Driver SDK الحالية التي تمت إضافتها باستخدام CocoaPods، اتّبِع الخطوات التالية:

    1. أغلِق مساحة عمل Xcode. افتح الوحدة الطرفية ونفِّذ الأمر التالي:
      sudo gem install cocoapods-deintegrate cocoapods-clean 
      pod deintegrate 
      pod cache clean --all
    2. عليك إزالة Podfile وPodfile.resolved وXcode workspace في حال عدم استخدامها لأي منتج آخر غير CocoaPods.

    لإزالة حزمة "SDK لبرنامج التشغيل" الحالية التي تم تثبيتها يدويًا، اتّبِع الخطوات التالية:

    1. من إعدادات ضبط مشروع Xcode، ابحث عن Frameworks والمكتبات والمحتوى المضمّن. استخدِم علامة الطرح(-) لإزالة إطار العمل التالي:

      • GoogleRidesharingDriver.xcframework
    2. يجب إزالة حزمة GoogleRidesharingDriver من دليل المستوى الأعلى لمشروع Xcode.

    CocoaPods

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

    • أداة CocoaPods: لتثبيت هذه الأداة، افتح المحطة الطرفية وشغِّل الأمر التالي.
       sudo gem install 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 لفتح المشروع.

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

    التثبيت اليدوي

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

    تنزيل البرنامج الثنائي لحزمة SDK ومواردها:

    1. استخرِج الملفات للوصول إلى XCFramework والموارد.

    2. شغِّل Xcode وافتح مشروعًا حاليًا أو أنشئ مشروعًا جديدًا. إذا كنت مستخدِمًا جديدًا لنظام التشغيل iOS، أنشئ مشروعًا جديدًا واختَر نموذج تطبيق iOS.

    3. أنشئ مجموعة أطر العمل ضمن مجموعة مشروعك إذا لم تكن موجودة بالفعل.

    4. لتثبيت Driver SDK، اسحب ملف GoogleRidesharingDriver.xcframework إلى مشروعك ضمن إطارات الأطر، والمكتبات، والمحتوى المضمَّن. عندما يُطلب منك، حدد نسخ العناصر إذا لزم الأمر.

    5. اسحب ملف GoogleRidesharingDriver.bundle الذي تم تنزيله إلى دليل المستوى الأعلى في مشروع Xcode. اختَر "Copy items if needed" عندما يُطلب منك ذلك.

    6. حدد مشروعك من Project Navigator واختر هدف تطبيقك.

    7. افتح علامة التبويب "مراحل الإنشاء"، وفي "ربط النظام الثنائي مع المكتبات"، أضف أطر العمل والمكتبات التالية إذا لم تكن موجودة بالفعل:

      • Accelerate.framework
      • AudioToolbox.framework
      • AVFoundation.framework
      • CoreData.framework
      • CoreGraphics.framework
      • CoreLocation.framework
      • CoreTelephony.framework
      • CoreText.framework
      • GLKit.framework
      • ImageIO.framework
      • libc++.tbd
      • libxml2.tbd
      • libz.tbd
      • LocalAuthentication.framework
      • OpenGLES.framework
      • QuartzCore.framework
      • SystemConfiguration.framework
      • UIKit.framework
      • WebKit.framework
    8. اختَر مشروعك بدلاً من هدف محدّد، وافتح علامة التبويب إعدادات الإنشاء. في القسم علامات رابط أخرى، أضِف -ObjC لكل من تصحيح الأخطاء والإصدار. إذا لم تظهر هذه الإعدادات، عليك تغيير الفلتر في شريط "إعدادات الإصدار" من أساسي إلى الكل.

    إضافة ملف بيان الخصوصية في Apple

    1. نزِّل حزمة "بيان الخصوصية" لحزمة تطوير البرامج (SDK) لخدمة Drive لنظام التشغيل iOS: GoogleRidesharingDriverPrivacy.
    2. استخرِج الملف للوصول إلى GoogleRidesharingDriverPrivacy.bundle.
    3. انسخ GoogleRidesharingDriverPrivacy.bundle إلى دليل المستوى الأعلى لمشروع Xcode.

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

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

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

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

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

    ويكون رقم تعريف الموفِّر هو نفسه رقم تعريف مشروع Google Cloud. يمكنك الاطّلاع على دليل التشغيل السريع لمحرك الأسطول للحصول على مزيد من المعلومات.

    يقوم المثال التالي بتنفيذ موفر رمز دخول:

    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 وComedyID وdriverContext وaccessTokenProvider. ويكون معرِّف الخدمة هو نفسه رقم تعريف مشروع Google Cloud ويمكنك الوصول إلى مثيل GMTDVehicleReporter من driver API مباشرةً.

    ينشئ المثال التالي مثيل 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];
    }
    

    يمكنك الاستماع اختياريًا إلى أحداث AutomotiveReporter.

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

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

    • vehicleReporter(_:didSucceed:)

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

    • 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;