Driver SDK 是整合至驅動程式應用程式的程式庫。是 負責更新 Fleet Engine 與駕駛人的位置、路線 距離剩餘距離,以及預計到達時間這個 SDK 也整合了 Navigation SDK 為駕駛提供即時路線導航指示。
基本系統需求
必要條件
本指南假設您的應用程式已實作 Navigation SDK,且 機群引擎 皆已設定完成不過,範例程式碼提供 範例說明如何設定 Navigation SDK:
您也必須啟用 Maps SDK for iOS ,然後取得 API 金鑰。
取得使用權限
如果您是 Google Workspace 客戶,請建立
Workspace 群組,例如
在新手上路期間使用 google-maps-platform-sdk-users@workspacedomain.com
,以及
向 Google 提供名稱建議您採取這種做法。
您的 Workspace 群組會加入許可清單
會授予正確的 CocoaPods 存放區存取權。確認使用者
需要存取權的電子郵件和服務帳戶電子郵件都列在這份清單中。
如果貴機構無法建立 Workspace 群組,請將名單傳送給 Google 存取這些構件的使用者及服務帳戶電子郵件。
本機開發
如要進行本機開發,使用 Cloud SDK:
gcloud
gcloud auth login
用來登入的電子郵件地址必須是 Workspace 群組的成員。
自動化 (建構系統或持續整合)
根據以下項目設定自動化主機: 最佳做法:
如果您的程序是在 Google Cloud 環境中執行,請使用 自動 憑證偵測
否則,請將服務帳戶金鑰檔案儲存在 並將金鑰設為 GOOGLE_APPLICATION_CREDENTIALS 環境變數
與憑證相關聯的服務帳戶電子郵件地址必須是 開始練習
專案設定
您可以使用 CocoaPods 設定驅動程式 SDK。
使用 CocoaPods
如要使用 CocoaPods 設定 Driver SDK,您必須備妥下列項目:
- CocoaPods 工具:如要安裝此工具,請開啟終端機並執行
。
shell sudo gem install cocoapods
詳情請參閱 CocoaPods 入門指南 ,掌握更多詳細資訊。
建立驅動程式 SDK 的 Podfile,並使用該 Pod 來安裝 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 安裝指令。這個指令會安裝 Podfile 及其所有依附元件。
pod install
關閉 Xcode,然後開啟 (按兩下) 專案的 .xcworkspace 檔案 來啟動 Xcode從現在起,您必須使用 .xcworkspace 檔案 開啟專案
Alpha/Beta 版 SDK 版本
您需要設定 iOS 版 Driver SDK 的 Alpha 或 Beta 版本 下列項目:
CocoaPods 工具:如要安裝此工具,請開啟終端機並執行 。
sudo gem install cocoapods
詳情請參閱 CocoaPods 入門指南 ,掌握更多詳細資訊。
Google 存取清單上的開發人員帳戶。Pod 存放區 的 SDK 的 Alpha 和 Beta 版本並非公開來源。目的地: 存取這些版本,請與 Google 客戶工程師聯絡。 工程師會將您的開發帳戶新增至存取清單, 就會設定 Cookie 驗證。
當專案列入存取清單後,您就可以存取 Pod。
建立 iOS 專用 Driver SDK 的 Podfile,然後透過該 Pod 安裝 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 安裝指令。這個指令會安裝 Podfile 及其所有依附元件。
pod install
關閉 Xcode,然後開啟 (按兩下) 專案的 .xcworkspace 檔案 來啟動 Xcode從現在起,您必須使用 .xcworkspace 檔案 開啟專案
安裝 XCFramework
XCFramework 是用於安裝驅動程式 SDK 的二進位套件。這個套件可用於多個平台,包括使用 M1 晶片組的機器。 本指南說明如何手動將含有驅動程式 SDK 的 XCFramework 新增至專案,並在 Xcode 中進行建構設定。
下載 SDK 二進位檔和資源:
將壓縮的檔案解壓縮,以存取 XCFramework 和資源。
啟動 Xcode,然後開啟現有專案,或建立新專案。如果您是 iOS 新手,請建立新專案並選取 iOS 應用程式範本。
如果沒有架構群組,請在專案群組下建立。
將下載的
gRPCCertificates.bundle
檔案拖曳至 Xcode 專案的頂層目錄。畫面上出現提示時,請視需要選取「複製項目」。如要安裝驅動程式 SDK,請將
GoogleRidesharingDriver.xcframework
檔案拖曳到專案「Frameworks、Library 和 Embedded Content」下方。畫面上出現提示時,請視需要選取「複製項目」。將下載的
GoogleRidesharingDriver.bundle
拖曳至 Xcode 專案的頂層目錄。系統提示時,請選取Copy items if needed
。Select your project from the Project Navigator, and choose your application's target.
開啟「建構階段」分頁,然後在連結二進位檔和程式庫的連結二進位檔中,加入下列架構和程式庫 (如果尚未加入):
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 隱私權資訊清單檔案
Apple 要求在 App Store 上架應用程式,要求取得應用程式隱私權詳細資訊。如需最新資訊和其他資訊,請前往 Apple App Store 隱私權詳細資料頁面。
Apple 隱私權資訊清單檔案包含在 SDK 資源套件中。如要確認隱私權資訊清單檔案已納入並檢查其中的內容,請建立應用程式的封存檔案,然後從封存檔中產生隱私權報告。
實作授權和驗證
當驅動程式應用程式產生更新並傳送至 Fleet Engine 後端時,
要求必須包含有效的存取權杖。為了授權及
驗證這些要求之後,驅動程式 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
例項,您必須先建立
GMTDDeliveryDriverAPI
執行個體 (來自 providerID)
carID、driveContext 和 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