On-Demand-Lösungen für Fahrten und Lieferungen sind derzeit nur für ausgewählte Partner verfügbar.

Erste Schritte mit dem Driver SDK für iOS

Mit Sammlungen den Überblick behalten Sie können Inhalte basierend auf Ihren Einstellungen speichern und kategorisieren.

Sie können das Driver SDK verwenden, um eine verbesserte Navigation und Nachverfolgung für Ihre Fahrt- und Bestellfortschrittsanwendung zu ermöglichen. Das Driver SDK bietet für die Fleet Engine der On-Demand Rides and Deliveries-Lösung Fahrzeugstandort und Aufgabenaktualisierungen.

Mit dem Driver SDK werden die Fleet Engine-Dienste und Ihre benutzerdefinierten Dienste über den Standort und den Zustand des Fahrzeugs informiert. Beispielsweise kann das Fahrzeug ONLINE oder OFFLINE sein und der Fahrzeugstandort ändert sich während der Fahrt.

Mindestsystemanforderungen

Auf dem Mobilgerät muss iOS 12 oder höher installiert sein.

Voraussetzungen

In diesem Leitfaden wird davon ausgegangen, dass das Navigation SDK bereits in Ihrer App implementiert ist und das Fleet Engine-Back-End eingerichtet und verfügbar ist. Der Beispielcode enthält jedoch ein Beispiel für die Einrichtung des Navigation SDK.

Außerdem müssen Sie in Ihrem Google Cloud-Projekt das Maps SDK for iOS aktivieren und einen API-Schlüssel anfordern.

Projektkonfiguration

Sie können das Driver SDK mit CocoaPods konfigurieren.

Mit CocoaPods

Sie benötigen die folgenden Elemente, um das Driver SDK mit CocoaPods zu konfigurieren:

  • CocoaPods-Tool: Öffnen Sie das Terminal und führen Sie den folgenden Befehl aus, um dieses Tool zu installieren.

    sudo gem install cocoapods
    

    Weitere Informationen finden Sie im CocoaPods-Startleitfaden.

  • Ihr Entwicklerkonto auf der Google-Zugriffsliste Das Pod-Repository des SDKs ist nicht öffentlich. Wenden Sie sich an den Google Customer Engineer, um auf den Pod zuzugreifen. Der Entwickler fügt Ihr Entwicklerkonto zur Zugriffsliste hinzu und setzt ein Cookie für die Authentifizierung.

Nachdem sich Ihr Projekt in der Zugriffsliste befindet, können Sie auf den Pod zugreifen.

  1. Erstellen Sie eine Podfile für das Driver SDK und installieren Sie damit die API und ihre Abhängigkeiten: Erstellen Sie eine Datei mit dem Namen „Podfile“ in Ihrem Projektverzeichnis. Diese Datei definiert die Abhängigkeiten Ihres Projekts. Bearbeiten Sie die Podfile-Datei und fügen Sie Ihre Abhängigkeiten hinzu. Das folgende Beispiel enthält die Abhängigkeiten:

    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. Speichern Sie die Podfile. Öffnen Sie ein Terminal und rufen Sie das Verzeichnis mit der Podfile-Datei auf:

    cd <path-to-project>
    
  3. Führen Sie den Pod-Installationsbefehl aus. Dadurch werden die in der Podfile angegebenen APIs zusammen mit allen zugehörigen Abhängigkeiten installiert.

    pod install
    
  4. Schließen Sie Xcode und öffnen Sie dann die .xcworkspace-Datei Ihres Projekts (mit Doppelklick), um Xcode zu starten. Von nun an müssen Sie die .xcworkspace-Datei zum Öffnen des Projekts verwenden.

Autorisierung und Authentifizierung implementieren

Wenn Ihre Treiberanwendung Aktualisierungen an das Fleet Engine-Back-End generiert und sendet, müssen die Anfragen gültige Zugriffstokens enthalten. Zum Autorisieren und Authentifizieren dieser Anfragen ruft das Driver SDK Ihr Objekt gemäß dem Protokoll GMTDAuthorization auf. Das Objekt ist für die Bereitstellung des erforderlichen Zugriffstokens verantwortlich.

Als App-Entwickler wählen Sie aus, wie Tokens generiert werden. Die Implementierung sollte folgende Voraussetzungen erfüllen:

  • Zugriffstoken von einem HTTPS-Server abrufen, möglicherweise im JSON-Format.
  • Parst und speichert das Token.
  • Aktualisieren Sie das Token, wenn es abläuft.

Weitere Informationen zu den vom Fleet Engine-Server erwarteten Tokens finden Sie unter JSON-Webtoken (JWT) für die Autorisierung erstellen.

Die Anbieter-ID ist mit der Google Cloud-Projekt-ID identisch. Weitere Informationen finden Sie unter Fleet Engine-Kurzanleitung.

Im folgenden Beispiel wird ein Zugriffstokenanbieter implementiert:

Swift

import GoogleRidesharingDriver

private let providerURL = "INSERT_YOUR_TOKEN_PROVIDER_URL"

class SampleAccessTokenProvider: NSObject, GMTDAuthorization {
  private struct AuthToken {
    // The cached vehicle token.
    let token: String
    // Keep track of when the token expires for caching.
    let expiration: TimeInterval
    // Keep track of the vehicle ID the cached token is for.
    let vehicleID: String
  }

  enum AccessTokenError: Error {
    case missingAuthorizationContext
    case missingData
  }

  private var authToken: AuthToken?

  func fetchToken(
    with authorizationContext: GMTDAuthorizationContext?,
    completion: @escaping GMTDAuthTokenFetchCompletionHandler
  ) {
    // Get the vehicle ID from the authorizationContext. This is set by the Driver SDK.
    guard let authorizationContext = authorizationContext else {
      completion(nil, AccessTokenError.missingAuthorizationContext)
      return
    }
    let vehicleID = authorizationContext.vehicleID

    // If appropriate, use the cached token.
    if let authToken = authToken,
      authToken.expiration > Date.now.timeIntervalSince1970 && authToken.vehicleID == vehicleID
    {
      completion(authToken.token, nil)
      return
    }

    // Otherwise, try to fetch a new token from your server.
    let request = URLRequest(url: URL(string: providerURL))
    let task = URLSession.shared.dataTask(with: request) { [weak self] data, _, error in
      guard let strongSelf = self else { return }
      guard error == nil else {
        completion(nil, error)
        return
      }

      // Replace the following key values with the appropriate keys based on your
      // server's expected response.
      let vehicleTokenKey = "VEHICLE_TOKEN_KEY"
      let tokenExpirationKey = "TOKEN_EXPIRATION"
      guard let data = data,
        let fetchData = try? JSONSerialization.jsonObject(with: data) as? [String: Any],
        let token = fetchData[vehicleTokenKey] as? String,
        let expiration = fetchData[tokenExpirationKey] as? Double
      else {
        completion(nil, AccessTokenError.missingData)
        return
      }

      strongSelf.authToken = AuthToken(
        token: token, expiration: expiration, vehicleID: vehicleID)
      completion(token, nil)
    }
    task.resume()
  }
}

Objective-C

#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 {
  // 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 vehicletoken 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

RidesharingDriverAPI-Instanz erstellen

Um eine GMTDVehicleReporter-Instanz zu erhalten, müssen Sie zuerst eine GMTDRidesharingDriverAPI-Instanz mit der Feld „providerID“, „vehicleID“, „driveContext“ und „accessTokenProvider“ erstellen. Die providerID ist mit der Google Cloud-Projekt-ID identisch. Außerdem können Sie über die Treiber-API direkt auf die Instanz GMTDVehicleReporter zugreifen.

Im folgenden Beispiel wird eine GMTDRidesharingDriverAPI-Instanz erstellt:

Swift

import GoogleRidesharingDriver

private let providerID = "INSERT_YOUR_PROVIDER_ID"

class SampleViewController: UIViewController {
  private let mapView: GMSMapView

  override func viewDidLoad() {
    super.viewDidLoad()

    let vehicleID = "INSERT_CREATED_VEHICLE_ID"
    let accessTokenProvider = SampleAccessTokenProvider()
    let driverContext = GMTDDriverContext(
      accessTokenProvider: accessTokenProvider,
      providerID: providerID,
      vehicleID: vehicleID,
      navigator: mapView.navigator)
    let ridesharingDriverAPI = GMTDRidesharingDriverAPI(driverContext: driverContext)
  }
}

Objective-C

#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];

  GMTDRidesharingDriverAPI *ridesharingDriverAPI = [[GMTDRidesharingDriverAPI alloc] initWithDriverContext:driverContext];
}

Optional VehicleReporter-Ereignisse anhören

GMTDVehicleReporter aktualisiert das Fahrzeug regelmäßig, wenn locationTrackingEnabled den Wert true hat. Jedes Objekt kann gemäß dem Protokoll GMTDVehicleReporterListener GMTDVehicleReporter-Ereignisse abonnieren, um auf diese regelmäßigen Updates zu reagieren.

Sie können die folgenden Ereignisse verarbeiten:

  • vehicleReporter(_:didSucceed:)

    Informiert die Driver-App darüber, dass die Back-End-Dienste den Fahrzeugstandort und den Status aktualisiert haben.

  • vehicleReporter(_:didFail:withError:)

    Informiert den Listener darüber, dass ein Fahrzeugupdate fehlgeschlagen ist. Solange das Standort-Tracking aktiviert ist, sendet GMTDVehicleReporter weiterhin die neuesten Daten an das Fleet Engine-Back-End.

Im folgenden Beispiel werden diese Ereignisse verarbeitet:

Swift

import GoogleRidesharingDriver

private let providerID = "INSERT_YOUR_PROVIDER_ID"

class SampleViewController: UIViewController, GMTDVehicleReporterListener {
  private let mapView: GMSMapView

  override func viewDidLoad() {
    // Assumes you have implemented the sample code up to this step.
    ridesharingDriverAPI.vehicleReporter.add(self)
  }

  func vehicleReporter(_ vehicleReporter: GMTDVehicleReporter, didSucceed vehicleUpdate: GMTDVehicleUpdate) {
    // Handle update succeeded.
  }

  func vehicleReporter(_ vehicleReporter: GMTDVehicleReporter, didFail vehicleUpdate: GMTDVehicleUpdate, withError error: Error) {
    // Handle update failed.
  }
}

Objective-C

/*
 * 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 have implemented the sample code up to this step.
  [ridesharingDriverAPI.vehicleReporter addListener:self];
}

- (void)vehicleReporter:(GMTDVehicleReporter *)vehicleReporter didSucceedVehicleUpdate:(GMTDVehicleUpdate *)vehicleUpdate {
  // Handle update succeeded.
}

- (void)vehicleReporter:(GMTDVehicleReporter *)vehicleReporter didFailVehicleUpdate:(GMTDVehicleUpdate *)vehicleUpdate withError:(NSError *)error {
  // Handle update failed.
}

@end

GMTDVehicleReporter als Listener zu GMSRoadSnappedLocationProvider hinzufügen

Damit Standortupdates für das Driver SDK zur Verfügung stehen, muss GMTDVehicleReporter als Listener für GMSRoadSnappedLocationProvider festgelegt werden.

Swift

import GoogleRidesharingDriver

private let providerID = "INSERT_YOUR_PROVIDER_ID"

class SampleViewController: UIViewController, GMTDVehicleReporterListener {
  private let mapView: GMSMapView

  override func viewDidLoad() {
    // Assumes you have implemented the sample code up to this step.
    if let roadSnappedLocationProvider = mapView.roadSnappedLocationProvider {
      roadSnappedLocationProvider.add(ridesharingDriverAPI.vehicleReporter)
      roadSnappedLocationProvider.startUpdatingLocation()
    }
  }
}

Objective-C

/*
 * 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 have implemented the sample code up to this step.
  [_mapView.roadSnappedLocationProvider addListener:ridesharingDriverAPI.vehicleReporter];
  [_mapView.roadSnappedLocationProvider startUpdatingLocation];
}

@end

Standortermittlung aktivieren

Zum Aktivieren der Standortermittlung kann Ihre App locationTrackingEnabled auf GMTDVehicleReporter auf true setzen. GMTDVehicleReporter sendet automatisch Standortupdates. Nachdem die Dienste abgeglichen und das Fahrzeug einer Fahrt zugewiesen haben, sendet GMTDVehicleReporter automatisch Routenaktualisierungen, wenn sich GMSNavigator im Navigationsmodus befindet (wenn ein Ziel über setDestinations festgelegt ist).

Die Route, die du während der Fahrtaktualisierung festlegst, entspricht der Route, die der Fahrer während der Navigationssitzung verwendet. Damit die Freigabe von Reisen ordnungsgemäß funktioniert, sollte der über setDestinations festgelegte Wegpunkt mit dem Ziel im Fleet Engine-Back-End übereinstimmen.

Wenn locationTrackingEnabled auf true gesetzt ist, werden Fahrt- und Fahrzeugaktualisierungen in regelmäßigen Abständen basierend auf dem für locationUpdateInterval festgelegten Wert an das Fleet Engine-Back-End gesendet. Wenn locationTrackingEnabled auf false gesetzt ist, werden keine Updates mehr durchgeführt und eine endgültige Fahrzeugaktualisierungsanfrage wird an das Fleet Engine-Back-End gesendet, um den Fahrzeugstatus auf GMTDVehicleState.offline zu setzen. Siehe updateVehicleState besondere Überlegungen zur Behandlung von Fehlern, wenn locationTrackingEnabled auf false gesetzt ist.

Im folgenden Beispiel wird die Standortermittlung aktiviert:

Swift

import GoogleRidesharingDriver

private let providerID = "INSERT_YOUR_PROVIDER_ID"

class SampleViewController: UIViewController, GMTDVehicleReporterListener {
  private let mapView: GMSMapView

  override func viewDidLoad() {
    // Assumes you have implemented the sample code up to this step.
    ridesharingDriverAPI.vehicleReporter.locationTrackingEnabled = true
  }
}

Objective-C

/*
 * 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 have implemented the sample code up to this step.
  ridesharingDriverAPI.vehicleReporter.locationTrackingEnabled = YES;
}

@end

Standardmäßig beträgt das Berichtsintervall 10 Sekunden, aber es kann mit locationUpdateInterval geändert werden. Das mindestens unterstützte Updateintervall beträgt 1 Sekunde. Das maximal unterstützte Updateintervall beträgt 60 Sekunden. Häufigere Updates können zu langsameren Anfragen und Fehlern führen.

Fahrzeugstatus aktualisieren

Das folgende Beispiel zeigt, wie der Fahrzeugstatus auf ONLINE gesetzt wird. Weitere Informationen finden Sie unter updateVehicleState.

Swift

import GoogleRidesharingDriver

private let providerID = "INSERT_YOUR_PROVIDER_ID"

class SampleViewController: UIViewController, GMTDVehicleReporterListener {
  private let mapView: GMSMapView

  override func viewDidLoad() {
    // Assumes you have implemented the sample code up to this step.
    ridesharingDriverAPI.vehicleReporter.update(.online)
  }
}

Objective-C

#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 have implemented the sample code up to this step.
  [ridesharingDriverAPI.vehicleReporter
                                   updateVehicleState:GMTDVehicleStateOnline];
}

@end

Standortupdates deaktivieren und Fahrzeug offline schalten

Deine App kann Updates deaktivieren und das Fahrzeug offline schalten. Wenn beispielsweise ein Fahrzug endet, kann die Anwendung locationTrackingEnabled auf false setzen. Durch das Deaktivieren von Updates wird auch der Status des Fahrzeugs im Fleet Engine-Back-End auf OFFLINE gesetzt.

Swift

vehicleReporter.locationTrackingEnabled = false

Objective-C

_vehicleReporter.locationTrackingEnabled = NO;