ラスト ワンマイルのフリート ソリューションは現在、一部のお客様のみご利用いただけます。詳しくは、営業担当者までお問い合わせください。

Driver SDK for iOS スタートガイド

コレクションでコンテンツを整理 必要に応じて、コンテンツの保存と分類を行います。

Driver SDK は、ドライバアプリに統合するライブラリです。ドライバの場所、ルート、残りの距離、ETA は、フリート エンジンによって更新されます。また、Navigation SDK と統合されているため、ドライバーにターンバイターン方式のナビゲーション指示が提供されます。

最小システム要件

  • モバイル デバイスが iOS 12 以降を搭載している必要があります。
  • Xcodeバージョン 13 以降。
  • Prerequisites

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

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

    アクセス権を取得

    Google Workspace を使用している場合は、オンボーディング時に google-maps-platform-sdk-users@workspacedomain.com などのワークスペース グループを作成し、Google に名前を指定します。これはおすすめの方法です。 次に、ワークスペースが許可リストに追加され、適切な CocoaPods リポジトリへのアクセスが許可されます。アクセス権を必要とするユーザーのメールアドレスとサービス アカウントのメールアドレスがこのリストに含まれていることを確認します。

    組織で Workspace グループを作成できない場合は、これらのアーティファクトにアクセスする必要があるユーザーとサービス アカウントのメールアドレスのリストを Google に送信します。

    ローカルでの開発

    ローカル開発では、Cloud SDK でログインするだけで十分です。

    gcloud

    gcloud auth login
    

    ログインに使用するメールアドレスは、Workspace グループのメンバーである必要があります。

    自動化(ビルドシステムまたは継続的インテグレーション)

    ベスト プラクティスに従って自動化ホストを設定します。

    • プロセスが Google Cloud 環境内で実行されている場合は、自動認証情報検出を使用します。

    • それ以外の場合は、ホストのファイル システムの安全な場所にサービス アカウント キー ファイルを保存し、GOOGLE_APPLICATION_CREDENTIALS 環境変数を適切に設定します。

    認証情報に関連付けられたサービス アカウントのメールアドレスは、Workspace Goup のメンバーである必要があります。

    Project Configuration

    Driver SDK は CocoaPods を使用して設定できます。

    CocoaPods を使用

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

    • CocoaPods ツール: このツールをインストールするには、ターミナルを開いて次のコマンドを実行します。

      sudo gem install cocoapods
      

      詳細については、CocoaPods スタートガイドをご覧ください。

    • Google アクセスリストに記載されている開発用アカウント。この SDK の Pod リポジトリは公開ソースではありません。この Pod にアクセスするには、Google カスタマー エンジニアにお問い合わせください。エンジニアが、開発用アカウントをアクセスリストに追加し、認証用に Cookie を設定します。

    プロジェクトがアクセスリストに表示されると、Pod にアクセスできるようになります。

    1. Driver SDK の Podfile を作成し、それを使用して API とその依存関係をインストールします。プロジェクト ディレクトリに Podfile という名前のファイルを作成します。このファイルは、プロジェクトの依存関係を定義します。Podfile を編集して依存関係を追加します。依存関係を含む例を次に示します。

      source "https://cpdc-eap.googlesource.com/ridesharing-driver-sdk.git"
      source "https://cpdc-eap.googlesource.com/geo-nav-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 のインストール コマンドを実行します。これにより、Podfile で指定された API と、それらの依存関係(存在する場合)がインストールされます。

      pod install
      
    4. Xcode を終了してから、プロジェクトの .xcworkspace ファイルを開いて(ダブルクリックして)Xcode を起動します。それ以降は、.xcworkspace ファイルを使用してプロジェクトを開く必要があります。

    XCFramework をインストールする

    XCFramework は、Driver SDK のインストールに使用するバイナリ パッケージです。このパッケージは、M1 チップセットを使用しているマシンを含む複数のプラットフォームで使用できます。このガイドでは、Driver SDK を含む XCFramework をプロジェクトに手動で追加し、Xcode でビルド設定を構成する方法について説明します。

    1. Google から受け取ったソースファイルを展開します。

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

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

    4. XCFramework を含む zip の Resources ディレクトリに含まれる gRPCCertificates.bundle ファイルを、Xcode プロジェクトの最上位ディレクトリにドラッグします。画面の指示に沿って、必要に応じて [アイテムをコピー] を選択します。

    5. Driver SDK をインストールするには、GoogleRidesharingDriver.xcframework ファイルを Frameworks, Libraries, and Embedded Content の下のプロジェクトにドラッグします。画面の指示に沿って、必要に応じて [アイテムをコピー] を選択します。

    6. Project Navigator のプロジェクトを選択し、アプリのターゲットを選択します。

    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
      • OpenGLES.framework
      • QuartzCore.framework
      • SystemConfiguration.framework
      • UIKit.framework
      • LocalAuthentication.framework
      • WebKit.framework
    8. 特定のターゲットではなくプロジェクトを選択し、[Build Settings] タブを開きます。[Other Linker Flags] セクションで、デバッグとリリースの両方に ‑ObjC を追加します。これらの設定が表示されていない場合は、[Build Settings] バーのフィルタを [Basic] から [All] に変更します。

    認可と認証を実装する

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

    トークンの生成方法はアプリ デベロッパーが選択します。実装では、次の処理を行う必要があります。

    • HTTPS サーバーからアクセス トークンを(場合によっては JSON 形式で)フェッチします。
    • トークンを解析し、キャッシュに保存します。
    • 有効期限が切れたらトークンを更新します。

    Fleet Engine サーバーで想定されるトークンの詳細については、認可用の JSON ウェブトークン(JWT)の作成をご覧ください。

    プロバイダ ID は Google Cloud プロジェクト ID と同じです。詳しくは、Fleet Engine Deliveries API ユーザーガイドをご覧ください。

    次の例では、アクセス トークン プロバイダを実装しています。

    #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 {
      if (!completion) {
        NSAssert(NO, @"%s encountered an unexpected nil completion.", __PRETTY_FUNCTION__);
        return;
      }
    
      // 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 vehicle token 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
    

    DeliveryDriverAPI インスタンスを作成する

    GMTDDeliveryVehicleReporter インスタンスを取得するには、まず、providerID、vehicleID、driverContext、accessTokenProvider を使用して GMTDDeliveryDriverAPI インスタンスを作成する必要があります。providerID は、Google Cloud プロジェクト ID と同じです。そのため、ドライバ API から直接 GMTDDeliveryVehicleReporter インスタンスにアクセスできます。

    次の例では、GMTDDeliveryDriverAPI インスタンスを作成します。

    #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];
    
      GMTDDeliveryDriverAPI *deliveryDriverAPI = [[GMTDDeliveryDriverAPI alloc] initWithDriverContext:driverContext];
    }
    

    必要に応じて、VehicleReporter イベントをリッスンする

    GMTDDeliveryVehicleReporter は、locationTrackingEnabled が YES の場合、定期的に車両を更新します。こうした定期的な更新に対応するには、GMTDVehicleReporterListener プロトコルに準拠し、任意のオブジェクトを GMTDDeliveryVehicleReporter イベントに登録します。

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

    • vehicleReporter:didSucceedVehicleUpdate

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

    • vehicleReporter:didFailVehicleUpdate:withError

      車両の更新に失敗したことをリスナーに通知します。位置情報の追跡が有効になっている限り、GMTDDeliveryVehicleReporter は引き続き最新のデータを Fleet Engine バックエンドに送信します。

    次の例では、これらのイベントを処理します。

    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 IMPLEMENTED HAVE THE SAMPLE CODE UP TO THIS STEP.
      [ridesharingDriverAPI.vehicleReporter addListener:self];
    }
    
    - (void)vehicleReporter:(GMTDDeliveryVehicleReporter *)vehicleReporter didSucceedVehicleUpdate:(GMTDVehicleUpdate *)vehicleUpdate {
      // Handle update succeeded.
    }
    
    - (void)vehicleReporter:(GMTDDeliveryVehicleReporter *)vehicleReporter didFailVehicleUpdate:(GMTDVehicleUpdate *)vehicleUpdate withError:(NSError *)error {
      // Handle update failed.
    }
    
    @end
    

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

    位置情報のトラッキングを有効にするには、GMTDDeliveryVehicleReporterlocationTrackingEnabledYES に設定します。そうすると、GMTDDeliveryVehicleReporter が位置情報の更新を自動的に送信します。GMSNavigator がナビゲーション モード(setDestinations でデスティネーションが設定されている)で、locationTrackingEnabledYES に設定されている場合、GMTDDeliveryVehicleReporter はルートと到着予定時刻の更新も自動的に送信します。

    これらの更新中に設定されたルートは、ドライバーがナビゲーション セッション中に移動したルートと同じになります。したがって、配送追跡が正しく機能するには、-setDestinations:callback: を介して設定された地点が Fleet Engine バックエンドで設定された目的地と一致している必要があります。

    次の例では、位置情報トラッキングを有効にしています。

    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 IMPLEMENTED HAVE THE SAMPLE CODE UP TO THIS STEP.
      deliveryDriverAPI.vehicleReporter.locationTrackingEnabled = YES;
    }
    
    @end
    

    デフォルトではレポート間隔は 10 秒ですが、レポート間隔は locationUpdateInterval で変更できます。サポートされている最小更新間隔は 5 秒です。指定できる更新間隔は最大 60 秒です。更新を頻繁に行うと、リクエストやエラーが遅くなる可能性があります。

    位置情報の更新を無効にする

    アプリは、車両の位置情報の更新を無効にできます。たとえば、ドライバーのシフトが終了したら、アプリで locationTrackingEnabledNO に設定できます。

      _vehicleReporter.locationTrackingEnabled = NO