L'SDK Driver è una libreria che puoi integrare nell'app del conducente. È responsabile dell'aggiornamento di Fleet Engine con posizione, percorso, distanza rimanente e orario di arrivo stimato del conducente. Inoltre, si integra con l'SDK di navigazione, che fornisce istruzioni di navigazione passo passo per il conducente.
Requisiti minimi di sistema
Prerequisiti
Questa guida presuppone che la tua app implementi già l'SDK di navigazione e che il backend di Fleet Engine sia configurato e disponibile. Tuttavia, il codice di esempio fornisce un esempio di come configurare l'SDK di navigazione.
Devi inoltre attivare l'SDK Maps per iOS nel tuo progetto Google Cloud e ottenere una chiave API.
Accesso
Se sei un cliente Google Workspace, crea un gruppo Workspace, ad esempio google-maps-platform-sdk-users@workspacedomain.com
durante l'onboarding, e fornisci il nome a Google. Questo è l'approccio consigliato.
Il tuo gruppo Workspace verrà quindi aggiunto a una lista consentita che concede l'accesso ai repository CocoaPods corretti. Verifica che gli indirizzi email degli utenti e degli account di servizio che richiedono l'accesso siano inclusi in questo elenco.
Se la tua organizzazione non può creare gruppi Workspace, invia a Google un elenco di email di account utente e di servizio che richiedono l'accesso a questi elementi.
Sviluppo locale
Per lo sviluppo locale, è sufficiente accedere con Cloud SDK.
gcloud
gcloud auth login
L'email utilizzata per accedere deve essere membro del gruppo Workspace.
Automazione (sistemi di creazione o integrazione continua)
Configura gli host di automazione in base alle best practice:
Se il tuo processo viene eseguito all'interno di un ambiente Google Cloud, utilizza il rilevamento delle credenziali automatico.
In caso contrario, archivia il file della chiave dell'account di servizio in una posizione sicura sul file system dell'host e imposta la variabile di ambiente GOOGLE_APPLICATION_CREDENTIALS in modo appropriato.
L'indirizzo email dell'account di servizio associato alle credenziali deve essere un membro del gruppo Workspace.
Configurazione progetto
Puoi configurare l'SDK Driver utilizzando CocoaPods.
Usa CocoaPods
Per configurare l'SDK Driver utilizzando CocoaPods, sono necessari i seguenti elementi:
- Lo strumento CocoaPods: per installare lo strumento, apri il terminale ed esegui questo comando.
shell sudo gem install cocoapods
Per ulteriori dettagli, consulta la Guida introduttiva di CocoaPods.
Crea un podfile per l'SDK Driver e utilizzalo per installare l'API e le sue dipendenze: crea un file denominato Podfile nella directory del progetto. Questo file definisce le dipendenze del progetto. Modifica il podfile e aggiungi le tue dipendenze. Ecco un esempio che include le dipendenze:
source "https://github.com/CocoaPods/Specs.git" target 'YOUR_APPLICATION_TARGET_NAME_HERE' do pod 'GoogleRidesharingDriver' end
Salva il podfile. Apri un terminale e vai alla directory contenente il Podfile:
cd <path-to-project>
Esegui il comando di installazione dei pod. Questa operazione installerà le API specificate nel podfile, insieme alle eventuali dipendenze.
pod install
Chiudi Xcode, quindi apri (doppio clic) il file .xcworkspace del progetto per avviare Xcode. D'ora in poi, per aprire il progetto dovrai usare il file .xcworkspace.
Versioni SDK alpha/beta
Per configurare le versioni alpha o beta dell'SDK Driver per iOS sono necessari i seguenti elementi:
Lo strumento CocoaPods: per installare lo strumento, apri il terminale ed esegui questo comando.
sudo gem install cocoapods
Per ulteriori dettagli, consulta la Guida introduttiva di CocoaPods.
Il tuo account di sviluppo nell'elenco di accesso di Google. Il repository di pod delle versioni alpha e beta dell'SDK non è di origine pubblica. Per accedere a queste versioni, contatta il Google Customer Engineer. Il tecnico aggiunge il tuo account di sviluppo all'elenco per gli accessi e quindi imposta un cookie per l'autenticazione.
Quando il progetto è nell'elenco per gli accessi, puoi accedere al pod.
Crea un podfile per l'SDK Driver per iOS e utilizzalo per installare l'API e le sue dipendenze: crea un file denominato Podfile nella directory del progetto. Questo file definisce le dipendenze del progetto. Modifica il podfile e aggiungi le tue dipendenze. Ecco un esempio che include le dipendenze:
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
Salva il podfile. Apri un terminale e vai alla directory contenente il Podfile:
cd <path-to-project>
Esegui il comando di installazione dei pod. Questa operazione installerà le API specificate nel podfile, insieme alle eventuali dipendenze.
pod install
Chiudi Xcode, quindi apri (doppio clic) il file .xcworkspace del progetto per avviare Xcode. D'ora in poi, per aprire il progetto dovrai usare il file .xcworkspace.
Installare XCFramework
Un XCFramework è un pacchetto binario che puoi utilizzare per installare l'SDK Driver. Puoi utilizzare questo pacchetto su più piattaforme, incluse le macchine che utilizzano il chipset M1. Questa guida mostra come aggiungere manualmente al progetto l'XCFramework contenente l'SDK dei driver e configurare le impostazioni di build in Xcode.
Scarica il file binario e le risorse dell'SDK:
Decomprimi i file compressi per accedere a XCFramework e alle risorse.
Avvia Xcode e apri un progetto esistente o creane uno nuovo. Se è la prima volta che utilizzi iOS, crea un nuovo progetto e seleziona il modello di app per iOS.
Crea un gruppo di framework nel gruppo di progetto, se non ne esiste già uno.
Trascina il file
gRPCCertificates.bundle
scaricato nella directory di primo livello del tuo progetto Xcode. Quando richiesto, seleziona Copia elementi, se necessario.Per installare l'SDK Driver, trascina il file
GoogleRidesharingDriver.xcframework
nel progetto in Framework, librerie e contenuti incorporati. Quando richiesto, seleziona Copia elementi, se necessario.Trascina l'oggetto
GoogleRidesharingDriver.bundle
scaricato nella directory di primo livello del tuo progetto Xcode. Quando richiesto, selezionaCopy items if needed
.Seleziona il tuo progetto dal navigatore dei progetti e scegli il target della tua applicazione.
Apri la scheda Fasi di creazione e, in Collega binario con le librerie, aggiungi i framework e le librerie seguenti se non sono già presenti:
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
Scegli il progetto anziché una destinazione specifica e apri la scheda Impostazioni build. Nella sezione Altri flag linker, aggiungi
‑ObjC
sia per il debug che per la release. Se queste impostazioni non sono visibili, modifica il filtro nella barra delle impostazioni della build da Di base a Tutte.
Ispeziona il file manifest della privacy di Apple
Apple richiede informazioni sulla privacy per le app disponibili sull'App Store. Visita la pagina dei dettagli sulla privacy dell'App Store di Apple per aggiornamenti e ulteriori informazioni.
Il file manifest della privacy di Apple è incluso nel bundle di risorse per l'SDK. Per verificare che il file manifest per la privacy sia stato incluso e per controllarne i contenuti, crea un archivio della tua app e genera una segnalazione sulla privacy dall'archivio.
Implementare l'autorizzazione e l'autenticazione
Quando l'app Driver genera e invia aggiornamenti al backend Fleet Engine,
le richieste devono includere token di accesso validi. Per autorizzare e autenticare queste richieste, l'SDK Driver chiama il tuo oggetto conforme al protocollo GMTDAuthorization
. L'oggetto è responsabile di fornire il token di accesso richiesto.
In qualità di sviluppatore dell'app, sei tu a scegliere il modo in cui vengono generati i token. La tua implementazione deve offrire la possibilità di:
- Recupera un token di accesso, possibilmente in formato JSON, da un server HTTPS.
- Analizza e memorizza nella cache il token.
- Aggiorna il token alla scadenza.
Per maggiori dettagli sui token previsti dal server Fleet Engine, consulta Creazione di un token web JSON (JWT) per l'autorizzazione.
L'ID provider corrisponde all'ID progetto Google Cloud. Per ulteriori informazioni, consulta la guida dell'utente dell'API Fleet Engine Deliveries.
L'esempio seguente implementa un provider di token di accesso:
#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
Crea un'istanza DeliveryDriverAPI
Per ottenere un'istanza GMTDDeliveryVehicleReporter
, devi prima creare un'istanza
GMTDDeliveryDriverAPI
utilizzando providerID,
vehicleID, driverContext e accessTokenProvider. Il providerID corrisponde all'ID
del progetto Google Cloud. Puoi accedere all'istanza GMTDDeliveryVehicleReporter
direttamente dall'API driver.
L'esempio seguente crea un'istanza 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];
}
Facoltativamente, ascolta gli eventi di VehicleReporter
GMTDDeliveryVehicleReporter
aggiorna periodicamente il veicolo quando
locationTrackingEnabled
è impostato su SÌ. Per rispondere a questi aggiornamenti periodici, qualsiasi oggetto può sottoscrivere gli eventi GMTDDeliveryVehicleReporter
conformemente al protocollo GMTDVehicleReporterListener
.
Puoi gestire i seguenti eventi:
vehicleReporter:didSucceedVehicleUpdate
Informa l'app del conducente che i servizi di backend hanno ricevuto correttamente la posizione e l'aggiornamento dello stato del veicolo.
vehicleReporter:didFailVehicleUpdate:withError
Informa il listener che un aggiornamento del veicolo non è riuscito. Finché il monitoraggio della posizione è abilitato,
GMTDDeliveryVehicleReporter
continua a inviare i dati più recenti al backend di Fleet Engine.
Nell'esempio seguente vengono gestiti questi eventi:
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
Attiva il monitoraggio della posizione
Per attivare il monitoraggio della posizione, la tua app può impostare locationTrackingEnabled
su YES
su GMTDDeliveryVehicleReporter
. Dopodiché GMTDDeliveryVehicleReporter
invierà automaticamente aggiornamenti sulla posizione. Quando GMSNavigator
è in modalità di navigazione (quando una destinazione è impostata tramite setDestinations
) e locationTrackingEnabled
è impostato su YES
, GMTDDeliveryVehicleReporter
invia automaticamente anche aggiornamenti sul percorso e sull'orario di arrivo stimato.
Il percorso impostato durante questi aggiornamenti sarà lo stesso percorso dal conducente durante la sessione di navigazione. Pertanto, affinché il monitoraggio della spedizione funzioni correttamente, il waypoint impostato tramite -setDestinations:callback:
deve corrispondere alla destinazione impostata nel backend di Fleet Engine.
Il seguente esempio abilita il monitoraggio della posizione:
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
Per impostazione predefinita, l'intervallo del report è di 10 secondi, ma l'intervallo può essere modificato con locationUpdateInterval
. L'intervallo di aggiornamento minimo supportato
è di 5 secondi. L'intervallo di aggiornamento massimo supportato è di 60 secondi. Aggiornamenti più frequenti possono comportare richieste ed errori più lenti.
Disattivare gli aggiornamenti della posizione
La tua app può disattivare gli aggiornamenti della posizione per un veicolo. Ad esempio, al termine
del turno di un conducente, l'app può impostare locationTrackingEnabled
su NO
.
_vehicleReporter.locationTrackingEnabled = NO
Gestire gli errori update_mask
Quando GMTDDeliveryVehicleReporter
invia un aggiornamento del veicolo, può verificarsi un errore update_mask
quando la maschera è vuota e in genere si verifica per il primo aggiornamento dopo l'avvio. Nell'esempio seguente viene illustrato come gestire l'errore:
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