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

يمكنك استخدام "حزمة تطوير البرامج (SDK) لبرنامج التشغيل" لتوفير إمكانية تنقّل وتتبُّع محسّنتَين لتطبيق "مستوى تقدُّم الرحلة والطلبات". توفر "حزمة تطوير البرامج (SDK) للسائق" موقع المركبة وتحديثات المهام لمحرّك الحلول عند الطلب لعمليات النقل والتسليم.

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

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

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

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

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

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

    مدير حزم Swift

    يمكن تثبيت حزمة تطوير البرامج (SDK) لبرنامج التشغيل من خلال Swift Package Manager. لإضافة حزمة SDK، تأكَّد من إزالة أي تبعيات حالية لحزمة تطوير البرامج (SDK) لبرنامج التشغيل.

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

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

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

    1. في حال الترقية من إصدار أقدم من 9.0.0، عليك إزالة الاعتماديات التالية: GoogleMapsBase وGoogleMapsCore وGoogleMapsM4B بعد الترقية. يجب عدم إزالة تبعية GoogleMaps. لمعرفة مزيد من المعلومات، يمكنك الاطّلاع على ملاحظات الإصدار 9.0.0.

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

      • GoogleMapsBase (للترقيات من الإصدارات السابقة على 9.0.0 فقط)
      • GoogleMapsCore (للترقيات من الإصدارات السابقة على 9.0.0 فقط)
      • GoogleMapsM4B (للترقيات من الإصدارات السابقة على 9.0.0 فقط)
    2. من Xcode، انتقِل إلى "ملف" > "الحِزم" > "تحديث إلى أحدث إصدارات الحزمة".
    3. للتحقّق من عملية التثبيت، انتقِل إلى القسم تبعيات الحزمة في 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.

    لإزالة تثبيت Driver SDK الحالي يدويًا، اتبع الخطوات التالية:

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

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

    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
      

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

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

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

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

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

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

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

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

    7. افتح علامة التبويب "مراحل الإنشاء"، وفي "Link Binary with Libraries" (رابط Binary مع المكتبات)، أضف أطر العمل والمكتبات التالية إذا لم تكن موجودة بالفعل:

      • 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

    تشترط Apple تفاصيل خصوصية التطبيقات للتطبيقات المتوفّرة على App Store. يُرجى الانتقال إلى صفحة تفاصيل خصوصية Apple App Store لمعرفة آخر الأخبار ومزيد من المعلومات.

    1. نزِّل حزمة بيان الخصوصية لحزمة تطوير البرامج (SDK) لبرنامج التشغيل iOS: GoogleRidesharingDriverPrivacy.
    2. استخرِج الملف للوصول إلى "GoogleRidesharingDriverPrivacy.bundle".
    3. أضِف GoogleRidesharingDriverPrivacy.bundle إلى أداة التنقّل في مشروع Xcode باستخدام إحدى هذه الطرق. تأكّد من وضع علامة في المربّع "إضافة إلى الاستهدافات" لتحديد الاستهداف الذي يستهدفه تطبيقك. بعد إضافة ملف PrivacyInfo، سيظهر في أداة التنقّل في المشروع، ويمكنك فحص القيم.
    4. لقطة شاشة لمعلومات خصوصية Xcode
    5. تحقَّق من إضافة بيان الخصوصية من خلال إنشاء أرشيف لتطبيقك وإنشاء تقرير خصوصية من الأرشيف.

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

    عندما ينشئ تطبيق Driver تحديثات في الخلفية Fleet Engine ويرسلها، يجب أن تتضمّن الطلبات رموز دخول صالحة. للموافقة على هذه الطلبات ومصادقتها، تطلب "حزمة تطوير البرامج (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
    

    إنشاء مثيل RideshareDriverAPI

    للحصول على النسخة الافتراضية من GMTDVehicleReporter، عليك أولاً إنشاء مثيل GMTDRidesharingDriverAPI باستخدام providerID وAssetID و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];
    }
    

    الاستماع بشكل اختياري إلى أحداث AutomotiveReporter

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

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

    • vehicleReporter(_:didSucceed:)

      تُعلم تطبيق 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

    لتوفير تحديثات الموقع الجغرافي في "حزمة تطوير البرامج (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;