Driver SDK 是整合至驅動程式應用程式的程式庫。是 負責更新 Fleet Engine 與駕駛人的位置、路線 距離剩餘距離,以及預計到達時間這個 SDK 也整合了 Navigation SDK 為駕駛提供即時路線導航指示。
基本系統需求
必要條件
本指南假設您的應用程式已實作 Navigation SDK,且 機群引擎 皆已設定完成不過,範例程式碼提供 範例說明如何設定 Navigation SDK:
您也必須啟用 Maps SDK for iOS ,然後取得 API 金鑰。
本機開發
如要進行本機開發,使用 Cloud SDK:
gcloud
gcloud auth login
用來登入的電子郵件地址必須是 Workspace 群組的成員。
自動化 (建構系統或持續整合)
根據以下項目設定自動化主機: 最佳做法:
如果您的程序是在 Google Cloud 環境中執行,請使用 自動 憑證偵測
否則,請將服務帳戶金鑰檔案儲存在 並將金鑰設為 GOOGLE_APPLICATION_CREDENTIALS 環境變數
與憑證相關聯的服務帳戶電子郵件地址必須是 開始練習
專案設定
Swift 套件管理工具
您可以透過 Swift 套件管理工具。如要新增 SDK,請確認您具備 已移除所有現有的驅動程式 SDK 依附元件
如要將 SDK 加入新專案或現有專案,請按照下列步驟操作:
-
開啟 Xcode
project
或workspace
,然後依序前往「File」>新增套件依附元件。 - 輸入 https://github.com/googlemaps/ios-driver-sdk 做為網址,然後按下 Enter 鍵 來提取套件,然後點選「Add Package」
-
如要安裝特定
version
,請將「Dependency Rule」(依附元件規則) 欄位設為 版本化選項如果是新專案,建議您指定最新版本 使用「完全比對版本」如果有需要 SQL 指令的分析工作負載 則 BigQuery 可能是最佳選擇完成後,點選「新增套件」。 -
在「Choose Package Products」視窗中,確認
GoogleRidesharingDriver
將新增至 您指定的main
目標完成後,點選「新增套件」。 -
如要驗證安裝狀態,請前往目標的
General
窗格。 在「Frameworks、Library and Embedded Content」中應會顯示已安裝的套件。 您也可以查看「套件依附元件」「專案導覽器」的 驗證套件及其版本
如要更新現有專案的 package
,請按照下列步驟操作:
如果要升級的是 9.0.0 以下版本,請務必移除 下列依附元件:
GoogleMapsBase
、GoogleMapsCore
和 升級後的費用為GoogleMapsM4B
。請勿移除以下項目的依附元件:GoogleMaps
。詳情請參閱 9.0.0 版本資訊。在 Xcode 專案配置設定中,找到「Frameworks, libraries」 和嵌入內容請使用減號(-) 移除下列架構:
GoogleMapsBase
(僅適用於 9.0.0 以下版本的升級作業)GoogleMapsCore
(僅適用於 9.0.0 以下版本的升級作業)GoogleMapsM4B
(僅適用於 9.0.0 以下版本的升級作業)
- 在 Xcode 中,前往 [檔案] >套裝行程 >更新至最新套件版本」。
- 如要驗證安裝狀態,請前往「Project Navigator」的「Package Dependencies」部分 驗證套件及其版本
如要移除現有驅動程式 SDK 依附元件,請使用
CocoaPods
,請按照下列步驟操作:
- 關閉 Xcode 工作區。開啟終端機並執行下列指令:
sudo gem install cocoapods-deintegrate cocoapods-clean pod deintegrate pod cache clean --all
-
移除
Podfile
、Podfile.resolved
和 如果不是 CocoaPods,則使用 Xcodeworkspace
。
移除已安裝的現有驅動程式 SDK 手動操作,步驟如下:
在 Xcode 專案配置設定中,找出 Frameworks、 程式庫和嵌入內容使用減號
(-)
即可移除 下列架構:GoogleRidesharingDriver.xcframework
從 Xcode 專案的頂層目錄中,移除
GoogleRidesharingDriver
軟體包。
CocoaPods
如要使用 CocoaPods 設定 Driver SDK,您必須備妥下列項目:
- CocoaPods 工具:如要安裝此工具,請開啟終端機並執行 。
sudo gem install cocoapods
建立驅動程式 SDK 的 Podfile,然後透過該 Pod 安裝 API 其依附元件:在專案目錄中建立名為 Podfile 的檔案。 這個檔案定義了專案的依附元件。編輯 Podfile 依附元件以下是包含依附元件的範例:
source "https://github.com/CocoaPods/Specs.git" target 'YOUR_APPLICATION_TARGET_NAME_HERE' do pod 'GoogleRidesharingDriver' end
以下這個範例包含了 使用驅動程式 SDK 做為依附元件:
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 檔案即可開啟專案。
請參閱 CocoaPods 入門指南 指南 詳細資料。
手動安裝程式庫
XCFramework 是二進位套件,用來安裝 驅動程式 SDK。這個套件可用於多個項目 平台,包括使用 Apple silicon。本指南說明如何 手動新增包含 將 SDK 驅動程式至專案,並設定建構作業 設定。
下載 SDK 二進位檔和資源:
解壓縮檔案以存取 XCFramework 和資源。
啟動 Xcode 並開啟現有專案,或建立新專案 專案。如果您是 iOS 新手,請建立新專案並選取 應用程式範本。
如果沒有架構群組,請在專案群組下建立該架構群組
如要安裝驅動程式 SDK,請拖曳 將
GoogleRidesharingDriver.xcframework
個檔案匯入專案 架構、程式庫和嵌入內容。在系統提示時選取 視需要複製項目。將下載的
GoogleRidesharingDriver.bundle
拖曳到頂層 目錄。系統提示時,請選取Copy items if needed
。從「Project Navigator」中選取專案,然後選擇 並指定應用程式的目標
開啟「建構階段」分頁,然後在「連結二進位檔」和「程式庫的連結二進位檔」中,新增 下列架構和程式庫 (如果尚未提供):
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」 設定標籤。在 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