驱动程序 SDK 使用入门 (iOS)

您可以使用 Driver SDK 为“行程和订单进度”应用提供增强的导航和跟踪功能。Driver SDK 可为按需乘车和送货解决方案舰队引擎提供车辆位置和任务更新。

Driver SDK 可让 Fleet Engine 服务和您的自定义服务了解车辆的位置和状态。例如,车辆可以是 ONLINEOFFLINE,并且车辆位置会随着行程的进行而变化。

最低系统要求

  • 移动设备必须搭载 iOS 14 或更高版本。
  • Xcode 版本 15 或更高版本。
  • 前提条件

    本指南假定您的应用已实现 Navigation SDK,并且 Fleet Engine 后端已设置且可用。不过,示例代码提供了如何设置 Navigation SDK 的示例。

    您还必须在 Google Cloud 项目中启用 Maps SDK for iOS,并获取 API 密钥

    项目配置

    Swift Package Manager

    驱动程序 SDK 可通过 Swift Package Manager 安装。要添加该 SDK,请确保您已移除所有现有的驱动程序 SDK 依赖项。

    如需将 SDK 添加到新项目或现有项目,请按以下步骤操作:

    1. 打开 Xcode projectworkspace,然后依次点击 File > Add Package Dependencies
    2. 输入 https://github.com/googlemaps/ios-driver-sdk 作为网址,按 Enter 键提取软件包,然后点击“添加软件包”。
    3. 如需安装特定的 version,请将依赖项规则字段设置为某个基于版本的选项。对于新项目,我们建议指定最新版本并使用“确切版本”选项。完成后,点击“添加软件包”。
    4. Choose Package Products 窗口中,验证 GoogleRidesharingDriver 是否会添加到您指定的 main 目标。完成后,点击“添加软件包”。
    5. 如需验证您的安装,请前往目标的 General 窗格。在框架、库和嵌入式内容中,您应该会看到已安装的软件包。 您还可以查看“Project Navigator”的“Package Dependencies”部分,验证软件包及其版本。

    如需更新现有项目的 package,请按以下步骤操作:

    1. 如果您要从 9.0.0 之前的版本升级,则必须在升级后移除以下依赖项:GoogleMapsBaseGoogleMapsCoreGoogleMapsM4B。请勿移除 GoogleMaps 的依赖项。如需了解详情,请参阅版本 9.0.0 版本说明

      在您的 Xcode 项目配置设置中,找到框架、库和嵌入式内容。使用减号(-) 移除以下框架:

      • GoogleMapsBase(仅适用于从 9.0.0 之前的版本进行的升级)
      • GoogleMapsCore(仅适用于从 9.0.0 之前的版本进行的升级)
      • GoogleMapsM4B(仅适用于从 9.0.0 之前的版本进行的升级)
    2. 在 Xcode 中,转到“File”(文件)>“Packages”(软件包)>“Update To Latest Package Versions”(更新到最新软件包版本)。
    3. 如需验证安装,请前往 Project NavigatorPackage Dependencies 部分,验证软件包及其版本。

    如需移除使用 CocoaPods 添加的现有驱动程序 SDK 依赖项,请按以下步骤操作:

    1. 关闭 Xcode 工作区。打开终端并执行以下命令:
      sudo gem install cocoapods-deintegrate cocoapods-clean 
      pod deintegrate 
      pod cache clean --all
    2. 如果您不将 PodfilePodfile.resolved 和 Xcode workspace 用于 CocoaPods 之外的任何其他项目,请移除它们。

    如需移除手动安装的现有驱动程序 SDK,请按以下步骤操作:

    1. 在您的 Xcode 项目配置设置中,找到框架、库和嵌入式内容。使用减号(-)移除以下框架:

      • GoogleRidesharingDriver.xcframework
    2. 从 Xcode 项目的顶级目录中,移除 GoogleRidesharingDriver 软件包。

    CocoaPods

    要使用 CocoaPods 配置驱动程序 SDK,您需要具备以下条件:

    • CocoaPods 工具:如需安装此工具,请打开终端并运行以下命令。
       sudo gem install cocoapods
    
    1. 为驱动程序 SDK 创建 Podfile,并使用它来安装 API 及其依赖项:在项目目录中创建名为 Podfile 的文件。此文件定义项目的依赖项。修改 Podfile 并添加依赖项。以下是一个包含依赖项的示例:

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

      以下示例包含驱动程序 SDK 的 Alpha 版和 Beta 版 pod 作为依赖项:

      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 中指定的 API 及其可能具有的任何依赖项。

      pod install
      
    4. 关闭 Xcode,然后打开(双击)您项目的 .xcworkspace 文件以启动 Xcode。从此刻开始,您必须使用 .xcworkspace 文件打开项目。

    有关详情,请参阅 CocoaPods 入门指南

    手动安装

    XCFramework 是一个二进制软件包,用于安装驱动程序 SDK。您可以在多个平台上使用此软件包,包括使用 Apple 芯片的计算机。本指南介绍了如何将包含驱动程序 SDK 的 XCFramework 手动添加到项目中,并在 Xcode 中配置构建设置。

    下载 SDK 二进制文件和资源:

    1. 解压缩文件以访问 XCFramework 和资源。

    2. 启动 Xcode,然后打开现有项目或创建新项目。如果您刚开始接触 iOS,请创建一个新项目,并选择 iOS 应用模板。

    3. 在您的项目组下创建一个框架群组(如果还没有)。

    4. 如需安装驱动程序 SDK,请将 GoogleRidesharingDriver.xcframework 文件拖动到项目中的框架、库和嵌入式内容下。出现提示时,选择“Copy items if needed”。

    5. 将下载的 GoogleRidesharingDriver.bundle 拖动到 Xcode 项目的顶级目录中。出现提示时,选择 Copy items if needed

    6. 从项目导航器中选择您的项目,然后选择应用的目标。

    7. 打开“Build Phases”标签页,并在“Link Binary with Libraries”中添加以下框架和库(如果它们尚不存在):

      • 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. 选择您的项目(而不是具体的目标),并打开 Build Settings(构建设置)标签页。在 Other Linker Flags(其他链接器标记)部分中,为调试和发布添加 -ObjC。如果看不到这些设置,请将“构建设置”栏中的过滤条件从基本更改为全部

    添加 Apple 隐私清单文件

    Apple 要求为 App Store 中的应用提供应用隐私权详细信息。如需了解最新动态和更多信息,请访问 Apple App Store 隐私权详情页面

    1. 下载 iOS 版驱动程序 SDK 的 Privacy Manifest 软件包:GoogleRidesharingDriverPrivacy
    2. 解压该文件以访问 GoogleRidesharingDriverPrivacy.bundle
    3. 使用其中一种方法GoogleRidesharingDriverPrivacy.bundle 添加到 Xcode 项目导航器中。确保为您的应用的目标选中“添加到目标”复选框。添加后,PrivacyInfo 文件会显示在“项目”导航器中,您可以检查相应值。
    4. Xcode 隐私信息屏幕截图
    5. 通过为应用创建归档文件并从归档中生成隐私权报告,验证是否已添加隐私清单。

    实现授权和身份验证

    当您的驱动程序应用生成更新并将其发送到 Fleet Engine 后端时,请求必须包含有效的访问令牌。为了对这些请求进行授权和身份验证,驱动程序 SDK 会调用符合 GMTDAuthorization 协议的对象。该对象负责提供所需的访问令牌。

    作为应用开发者,您可以选择令牌的生成方式。您的实现应能够执行以下操作:

    • 从 HTTPS 服务器提取访问令牌(可能是 JSON 格式)。
    • 解析并缓存令牌。
    • 在令牌过期时刷新令牌。

    如需详细了解 Fleet Engine 服务器预期的令牌,请参阅创建 JSON Web 令牌 (JWT) 进行授权

    提供方 ID 与 Google Cloud 项目 ID 相同。如需了解详情,请参阅 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 实例,您首先需要使用 providerID、VehicleID、driverContext 和 accessTokenProvider 创建 GMTDRidesharingDriverAPI 实例。providerID 与 Google Cloud 项目 ID 相同。您可以直接通过驱动程序 API 访问 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 会定期在 locationTrackingEnabledtrue 时更新车辆。为了响应这些定期更新,任何对象都可以通过遵循 GMTDVehicleReporterListener 协议来订阅 GMTDVehicleReporter 事件。

    您可以处理以下事件:

    以下示例会处理这些事件:

    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
    

    启用位置跟踪

    如需启用位置跟踪,您的应用可以在 GMTDVehicleReporter 上将 locationTrackingEnabled 设置为 trueGMTDVehicleReporter 会自动发送位置信息更新。在服务匹配并将车辆分配给行程后,GMTDVehicleReporter 会在 GMSNavigator 处于导航模式(通过 setDestinations 设置目的地)时自动发送路线更新。

    在行程更新期间设置的路线与驾驶员在导航会话期间导航到的路线相同。因此,为确保行程共享正常运行,通过 setDestinations 设置的航点应与 Fleet Engine 后端中设置的目的地一致。

    如果 locationTrackingEnabled 设置为 true,系统会根据为 locationUpdateInterval 设置的值定期将行程和车辆更新发送到 Fleet Engine 后端。如果 locationTrackingEnabled 设置为 false,更新会停止,并且会向 Fleet Engine 后端发送最终的车辆更新请求,以将车辆状态设置为 GMTDVehicleState.offline。如需了解在 locationTrackingEnabled 设置为 false 时处理失败的特殊注意事项,请参阅 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.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。停用更新还会在 Fleet Engine 后端将车辆的状态设置为 OFFLINE

    Swift

    vehicleReporter.locationTrackingEnabled = false
    

    Objective-C

    _vehicleReporter.locationTrackingEnabled = NO;