Driver SDK は、ドライバアプリに統合するライブラリです。内容 ドライバーの位置情報、ルート、位置情報に基づいて Fleet Engine を 残り距離、到着予定時刻が表示されますまた、Navigation SDK との統合により、 ターンバイターン方式のナビをドライバーに提示します。
最小システム要件
前提条件
このガイドでは、アプリに Navigation SDK を実装し、 フリート エンジン 使用できることを確認します。サンプルコードでは こちらのサンプルをご覧ください。 Navigation SDK。
また、Maps SDK for iOS も有効にする必要があります。 」と入力して API キーを取得します。
アクセスの取得
Google Workspace をご利用の場合は、
Workspace グループ(例:
オンボーディング時の google-maps-platform-sdk-users@workspacedomain.com
、
提供します。これはおすすめの方法です。
これにより、Workspace グループが許可リストに追加され、
適切な CocoaPods リポジトリへのアクセス権を付与します。お客様が
メールアドレスとサービス アカウントのメールアドレスがこのリストに含まれます。
組織で Workspace グループを作成できない場合は、Google にリストを送信する ユーザー アカウントとサービス アカウントのメールアドレスが対象となります。
ローカルでの開発
ローカルで開発する場合は、 Cloud SDK。
gcloud
gcloud auth login
ログインに使用するメールアドレスは、Workspace グループのメンバーである必要があります。
自動化(ビルドシステムまたは継続的インテグレーション)
以下に従って自動化ホストを設定する ベスト プラクティス:
プロセスが Google Cloud 環境内で実行される場合は、 自動 認証情報の検出などを行います。
それ以外の場合は、サービス アカウント キー ファイルを 設定し、環境変数に GOOGLE_APPLICATION_CREDENTIALS 環境変数を適切に設定します。
認証情報に関連付けられたサービス アカウントのメールアドレスは、 。
Project Configuration
Driver SDK は CocoaPods を使用して構成できます。
CocoaPods を使用
CocoaPods を使用して Driver SDK を構成するには、次のものが必要です。
- CocoaPods ツール: このツールをインストールするには、ターミナルを開いて次のコマンドを実行します。
次のコマンドを実行します。
shell sudo gem install cocoapods
詳しくは、 CocoaPods スタートガイド をご覧ください。
Driver SDK 用の Podfile を作成し、それを使用して API とその依存関係: プロジェクトに Podfile という名前のファイルを作成します されます。このファイルでプロジェクトの依存関係を定義します。Podfile を編集する 依存関係を追加します。この例では :
source "https://github.com/CocoaPods/Specs.git" target 'YOUR_APPLICATION_TARGET_NAME_HERE' do pod 'GoogleRidesharingDriver' end
Podfile を保存します。ターミナルを開き、ターミナルを含むディレクトリに移動します。 Podfile:
cd <path-to-project>
Pod インストール コマンドを実行します。これにより、指定した API がインストールされます。 Podfile とそれらの依存関係が存在します。
pod install
Xcode を閉じて、プロジェクトの .xcworkspace ファイルを開く(ダブルクリック) Xcode を起動します。今後は、.xcworkspace ファイルを使用する必要があります。 プロジェクトを開きます。
アルファ版/ベータ版 SDK バージョン
Driver SDK for iOS のアルファ版またはベータ版を構成するには、以下が必要です。 次の項目があります。
CocoaPods ツール: このツールをインストールするには、ターミナルを開いて次のコマンドを実行します。 次のコマンドを実行します。
sudo gem install cocoapods
詳しくは、 CocoaPods スタートガイド をご覧ください。
Google アクセスリストの開発アカウント。Pod リポジトリ SDK のアルファ版とベータ版は公開ソースではありません。宛先 Google カスタマー エンジニアにお問い合わせください。 エンジニアが開発用アカウントをアクセスリストに追加し、 Cookie を設定します。 あります。
プロジェクトがアクセスリストに追加されると、Pod にアクセスできるようになります。
Driver SDK for iOS の Podfile を作成し、これを使用して API とその依存関係: プロジェクトに Podfile という名前のファイルを作成します されます。このファイルでプロジェクトの依存関係を定義します。Podfile を編集する 依存関係を追加します。この例では :
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
Podfile を保存します。ターミナルを開き、ターミナルを含むディレクトリに移動します。 Podfile:
cd <path-to-project>
Pod インストール コマンドを実行します。これにより、指定した API がインストールされます。 Podfile とそれらの依存関係が存在します。
pod install
Xcode を閉じて、プロジェクトの .xcworkspace ファイルを開く(ダブルクリック) Xcode を起動します。今後は、.xcworkspace ファイルを使用する必要があります。 プロジェクトを開きます。
XCFramework をインストールする
XCFramework は、Driver SDK のインストールに使用するバイナリ パッケージです。このパッケージは、M1 チップセットを搭載したマシンなど、複数のプラットフォームで使用できます。 このガイドでは、Driver SDK を含む XCFramework をプロジェクトに手動で追加し、Xcode でビルド設定を構成する方法について説明します。
SDK バイナリとリソースをダウンロードします。
圧縮されたファイルを解凍して、XCFramework とリソースにアクセスします。
Xcode を起動し、既存のプロジェクトを開くか、新しいプロジェクトを作成します。iOS を初めて使用する場合は、新しいプロジェクトを作成し、iOS アプリ テンプレートを選択します。
プロジェクト グループにフレームワーク グループを作成します(まだ存在しない場合)。
ダウンロードした
gRPCCertificates.bundle
ファイルを Xcode プロジェクトの最上位ディレクトリにドラッグします。プロンプトが表示されたら、必要に応じて [Copy items] を選択します。Driver SDK をインストールするには、[Frameworks, Libraries, and Embedded Content] の下のプロジェクトに
GoogleRidesharingDriver.xcframework
ファイルをドラッグします。プロンプトが表示されたら、必要に応じて [Copy items] を選択します。ダウンロードした
GoogleRidesharingDriver.bundle
を Xcode プロジェクトの最上位ディレクトリにドラッグします。プロンプトが表示されたら、[Copy items if needed
] を選択します。Project Navigator のプロジェクトを選択し、アプリのターゲットを選択します。
[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
特定のターゲットではなくプロジェクトを選択し、[Build Settings] タブを開きます。[Other Linker Flags] セクションで、デバッグとリリースの両方に
‑ObjC
を追加します。 これらの設定が表示されない場合は、[Build Settings] バーのフィルタを [Basic] から [All] に変更します。
Apple Privacy Manifest ファイルを調べる
Apple が App Store のアプリについては、アプリのプライバシーに関する詳細情報を必要とします。最新情報などについては、Apple App Store のプライバシーの詳細ページをご覧ください。
Apple Privacy Manifest ファイルは、SDK のリソース バンドルに含まれています。プライバシー マニフェスト ファイルが含まれていることを確認し、その内容を検査するには、アプリのアーカイブを作成し、そのアーカイブからプライバシー レポートを生成します。
認可と認証を実装する
ドライバアプリが更新を生成して Fleet Engine バックエンドに送信すると、
リクエストに有効なアクセス トークンを含める必要があります。Google Cloud で
Driver SDK はリクエストを認証するために、
GMTDAuthorization
構成されます。このオブジェクトは、必要なアクセス トークンを提供する役割を担います。
トークンの生成方法は、アプリ デベロッパーが選択します。お客様の実装 次の機能を提供する必要があります。
- HTTPS サーバーからアクセス トークン(JSON 形式など)をフェッチします。
- トークンを解析してキャッシュに保存します。
- 期限切れになったらトークンを更新します。
Fleet Engine サーバーによって予期されるトークンの詳細については、以下をご覧ください。 認可用の JSON Web Token(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 を使用して GMTDDeliveryDriverAPI
インスタンスを指定し、
VehicleID、driverContext、accessTokenProvider ですproviderID は
Google Cloud プロジェクト ID。また、GMTDDeliveryVehicleReporter
にアクセスできます。
ドライバ API から直接アクセスできます。
次の例では、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
は「はい」です。このような定期的な更新に対応するために、
オブジェクトは、次に準拠することで、GMTDDeliveryVehicleReporter
イベントをサブスクライブできます。
GMTDVehicleReporterListener
プロトコル。
次のイベントを処理できます。
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
位置情報追跡を有効にする
位置情報追跡を有効にするには、アプリで locationTrackingEnabled
を YES
に設定します。
(GMTDDeliveryVehicleReporter
)GMTDDeliveryVehicleReporter
は次のようになります。
自動的に現在地の更新情報が送信されます。GMSNavigator
がナビゲーション内にある場合
モード(デスティネーションが setDestinations
によって設定されている場合)
locationTrackingEnabled
が YES
に設定されます。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 秒です。頻繁
リクエストやエラーが遅くなる可能性があります。
位置情報の更新を無効にする
アプリは、車両の位置情報の更新を無効にすることができます。たとえば、
運転手のシフトが終了したときに、アプリで locationTrackingEnabled
を NO
に設定できます。
_vehicleReporter.locationTrackingEnabled = NO
update_mask エラーを処理する
GMTDDeliveryVehicleReporter
が車両の最新情報を送信すると、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