Driver SDK for iOS スタートガイド

Driver SDK を使用すると、「移動と注文の進行状況」アプリに、高度なナビゲーションとトラッキング機能を提供できます。Driver SDK は、オンデマンド配車と配達ソリューション Fleet Engine に車両の位置情報とタスクの更新を提供します。

Driver SDK は、Fleet Engine サービスとカスタム サービスが車両の位置と状態を認識できるようにします。たとえば、車両が ONLINE または OFFLINE の場合、車両の位置はルートの進行とともに変化します。

最小システム要件

  • モバイル デバイスに iOS 14 以降が搭載されている必要があります。
  • Xcode バージョン 15 以降。
  • 前提条件

    このガイドでは、アプリに Navigation SDK がすでに実装されており、Fleet Engine バックエンドが設定され、使用可能であることを前提としています。ただし、サンプルコードでは Navigation SDK をセットアップする方法を紹介しています。

    また、Google Cloud プロジェクトで Maps SDK for iOS を有効にし、API キーを取得する必要があります。

    Project Configuration

    Swift Package Manager

    Driver SDK は Swift Package Manager からインストールできます。SDK を追加するには、既存の Driver SDK の依存関係がすべて削除されていることを確認してください。

    新規または既存のプロジェクトに SDK を追加する手順は次のとおりです。

    1. Xcode の project または workspace を開き、[File] > [Add Package Dependencies] に移動します。
    2. URL として「https://github.com/googlemaps/ios-driver-sdk」と入力し、Enter キーを押してパッケージを取り込み、[Add Package] をクリックします。
    3. 特定の version をインストールするには、[依存関係ルール] フィールドをバージョン ベースのオプションのいずれかに設定します。新しいプロジェクトの場合は、最新バージョンを指定し、[正確なバージョン] オプションを使用することをおすすめします。完了したら、[パッケージを追加] をクリックします。
    4. [Choose Package Products] ウィンドウで、指定した main ターゲットに GoogleRidesharingDriver が追加されることを確認します。完了したら、[パッケージを追加] をクリックします。
    5. インストールを確認するには、ターゲットの General ペインに移動します。[Frameworks, Libraries, and Embedded Content] 内に、インストールされているパッケージが表示されます。 [Project Navigator] の [Package Dependencies] セクションで、パッケージとそのバージョンを確認することもできます。

    既存のプロジェクトの package を更新する手順は次のとおりです。

    1. Xcode で、[File] > [Packages] > [Update To Latest Package Versions] に移動します。
    2. インストールを確認するには、Project Navigator の [Package Dependencies] セクションに移動して、パッケージとそのバージョンを確認します。

    CocoaPods を使用して追加された既存の Driver SDK 依存関係を削除する手順は次のとおりです。

    1. Xcode ワークスペースを閉じます。ターミナルを開いて、次のコマンドを実行します。
      sudo gem install cocoapods-deintegrate cocoapods-clean 
      pod deintegrate 
      pod cache clean --all
    2. CocoaPods 以外に使用していない場合は、PodfilePodfile.resolved、Xcode の workspace を削除します。

    手動でインストールした既存の Driver SDK を削除する手順は次のとおりです。

    1. Xcode プロジェクトの構成設定で、フレームワーク、ライブラリ、埋め込みコンテンツを見つけます。マイナス記号 (-) を使用して、次のフレームワークを削除します。

      • GoogleRidesharingDriver.xcframework
    2. Xcode プロジェクトの最上位ディレクトリから、GoogleRidesharingDriver バンドルを削除します。

    CocoaPods

    CocoaPods を使用して Driver SDK を構成するには、次のものが必要です。

    • CocoaPods ツール: このツールをインストールするには、ターミナルを開いて次のコマンドを実行します。
       sudo gem install cocoapods
    
    1. Driver SDK の Podfile を作成し、それを使用して API とその依存関係をインストールします。プロジェクト ディレクトリに Podfile という名前のファイルを作成します。このファイルでプロジェクトの依存関係を定義します。Podfile を編集して、依存関係を追加します。依存関係を含む例を次に示します。

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

      次に、Driver SDK のアルファ版 Pod とベータ版 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 は、Driver SDK のインストールに使用するバイナリ パッケージです。このパッケージは、Apple シリコンを搭載したマシンなど、複数のプラットフォームで使用できます。このガイドでは、Driver SDK を含む XCFramework をプロジェクトに手動で追加し、Xcode でビルド設定を構成する方法について説明します。

    SDK のバイナリとリソースをダウンロードします。

    1. ファイルを抽出し、XCFramework とリソースにアクセスします。

    2. Xcode を起動し、既存のプロジェクトを開くか、新しいプロジェクトを作成します。iOS を初めて使用する場合は、新しいプロジェクトを作成し、iOS App テンプレートを選択します。

    3. フレームワーク グループがまだ存在しない場合は、プロジェクト グループの下に作成します。

    4. Driver SDK をインストールするには、GoogleRidesharingDriver.xcframework ファイルを [Frameworks, Libraries, and Embedded Content] の下にドラッグします。画面の指示に従って 必要に応じて [Copy items]を選択します

    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 を追加します。これらの設定が表示されない場合は、ビルド設定バーのフィルタを [Basic] から [All] に変更します。

    Apple のプライバシー マニフェスト ファイルを追加する

    1. Driver SDK for iOS のプライバシー マニフェスト バンドル(GoogleRidesharingDriverPrivacy)をダウンロードします。
    2. ファイルを解凍して GoogleRidesharingDriverPrivacy.bundle にアクセスします。
    3. 以下のいずれかの方法を使用して、GoogleRidesharingDriverPrivacy.bundle を Xcode プロジェクト ナビゲータに追加します。アプリのターゲットの [ターゲットに追加する] チェックボックスがオンになっていることを確認します。追加すると、PrivacyInfo ファイルがプロジェクト ナビゲータに表示され、値を調べることができます。
    4. Xcode のプライバシー情報のスクリーンショット
    5. アプリのアーカイブを作成し、そのアーカイブからプライバシー レポートを生成して、プライバシー マニフェストが追加されていることを確認します。

    認可と認証を実装する

    ドライバ アプリが更新を生成して Fleet Engine バックエンドに送信する場合、リクエストに有効なアクセス トークンを含める必要があります。これらのリクエストを承認して認証するために、Driver SDK は GMTDAuthorization プロトコルに準拠したオブジェクトを呼び出します。オブジェクトは、必要なアクセス トークンを提供する役割を担います。

    トークンの生成方法はアプリ デベロッパーが選択できます。実装では、次の機能を提供する必要があります。

    • HTTPS サーバーからアクセス トークンを(JSON 形式で取得できる)取得します。
    • トークンを解析してキャッシュに保存します。
    • トークンの有効期限が切れたら更新する。

    Fleet Engine サーバーで想定されるトークンの詳細については、認可用の JSON Web Token(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 と同じです。また、Driver 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 イベントをサブスクライブできます。

    次のイベントを処理できます。

    • vehicleReporter(_:didSucceed:)

      バックエンド サービスが車両の位置情報と状態の更新を正常に受信したことをドライバ アプリに通知します。

    • 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 に位置情報の更新データを提供するには、GMTDVehicleReporterGMSRoadSnappedLocationProvider のリスナーとして設定する必要があります。

    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
    

    位置情報の記録を有効にする

    位置情報の追跡を有効にするには、アプリの GMTDVehicleReporterlocationTrackingEnabledtrue に設定します。GMTDVehicleReporter は、位置情報の更新データを自動的に送信します。サービスが一致して車両をルートに割り当てた後、GMSNavigator がナビゲーション モードの場合(setDestinations で目的地が設定されている場合)、GMTDVehicleReporter はルートの更新情報を自動的に送信します。

    ルートの更新中に設定されるルートは、ドライバーがナビゲーション セッション中にナビゲーションするルートと同じになります。したがって、乗車経路の共有が適切に機能するには、setDestinations で設定されたウェイポイントが Fleet Engine バックエンドで設定された目的地と一致している必要があります。

    locationTrackingEnabledtrue に設定されている場合、ルートと車両の更新情報は、locationUpdateInterval に設定された値に基づいて一定の間隔で Fleet Engine バックエンドに送信されます。locationTrackingEnabledfalse に設定されている場合、アップデートは停止し、最後の車両アップデート リクエストが Fleet Engine バックエンドに送信され、車両の状態が GMTDVehicleState.offline に設定されます。locationTrackingEnabledfalse に設定されている場合の障害処理に関する特別な考慮事項については、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
    

    位置情報の更新を無効にして車をオフラインにする

    アプリは更新を無効にして、車をオフラインにできます。たとえば、ドライバーのシフトが終了したときに、アプリで locationTrackingEnabledfalse に設定できます。更新を無効にすると、Fleet Engine バックエンドで車両のステータスも OFFLINE に設定されます。

    Swift

    vehicleReporter.locationTrackingEnabled = false
    

    Objective-C

    _vehicleReporter.locationTrackingEnabled = NO;