Pierwsze kroki z pakietem SDK Driver na iOS

Pakiet Driver SDK to biblioteka zintegrowana z aplikacją kierowcy. Odpowiada za aktualizowanie informacji o lokalizacji pojazdu, trasie, pozostałym dystansie i szacowanym czasie dotarcia na miejsce. Jest też zintegrowany z pakietem Navigation SDK, który udostępnia kierowcom szczegółowe instrukcje nawigacji.

Minimalne wymagania systemowe

  • Urządzenie mobilne musi mieć zainstalowany system iOS 14 lub nowszy.
  • Xcode w wersji 15 lub nowszej.
  • Wymagania wstępne

    W tym przewodniku przyjęto, że Twoja aplikacja korzysta już z pakietu Navigation SDK, a backend Fleet Engine jest skonfigurowany i dostępny. Przykładowy kod zawiera jednak przykład konfiguracji pakietu Navigation SDK.

    Musisz też włączyć Maps SDK na iOS w projekcie Google Cloud i uzyskać klucz interfejsu API.

    Uzyskaj dostęp

    Jeśli jesteś klientem Google Workspace, podczas wprowadzenia utwórz grupę Workspace, taką jak google-maps-platform-sdk-users@workspacedomain.com, i podaj jej nazwę Google. To zalecane podejście. Twoja grupa Workspace zostanie dodana do listy dozwolonych, która przyznaje dostęp do odpowiednich repozytoriów CocoaPods. Sprawdź, czy na tej liście znajdują się adresy e-mail użytkowników i adresy e-mail kont usługi, które potrzebują dostępu.

    Jeśli Twoja organizacja nie może tworzyć grup Workspace, wyślij do Google listę adresów e-mail użytkowników i kont usługi, którzy potrzebują dostępu do tych artefaktów.

    Programowanie lokalne

    Aby można było programować lokalnie, wystarczy zalogować się za pomocą pakietu SDK Cloud.

    gcloud

    gcloud auth login
    

    Adres e-mail użyty do zalogowania musi należeć do grupy Workspace.

    Automatyzacja (tworzenie systemów lub ciągła integracja)

    Skonfiguruj hosty automatyzacji zgodnie ze sprawdzonymi metodami:

    • Jeśli proces działa w środowisku Google Cloud, użyj automatycznego wykrywania danych logowania.

    • W przeciwnym razie zapisz plik klucza konta usługi w bezpiecznej lokalizacji w systemie plików hosta i odpowiednio ustaw zmienną środowiskową GOOGLE_APPLICATION_CREDENTIALS.

    Adres e-mail konta usługi powiązany z danymi logowania musi należeć do grupy Workspace.

    Konfiguracja projektu

    Pakiet Driver SDK na iOS możesz skonfigurować ręcznie lub za pomocą Cocoapods.

    Używaj Cocoapods

    Aby skonfigurować pakiet Driver SDK dla iOS, potrzebujesz tych elementów:

    • Narzędzie CocoaPods: aby zainstalować to narzędzie, otwórz Terminal i uruchom następujące polecenie. shell sudo gem install cocoapods Więcej informacji znajdziesz we wprowadzeniu do CocoaPods.
    1. Utwórz plik Podfile dla pakietu Driver SDK na iOS i użyj go do zainstalowania interfejsu API i jego zależności: utwórz plik o nazwie Podfile w katalogu projektu. Ten plik definiuje zależności projektu. Edytuj plik Podfile i dodaj zależności. Oto przykład, który zawiera zależności:

      source "https://github.com/CocoaPods/Specs.git"
      
      target 'YOUR_APPLICATION_TARGET_NAME_HERE' do
        pod 'GoogleRidesharingDriver'
      end
      
    2. Zapisz plik Podfile. Otwórz terminal i przejdź do katalogu zawierającego plik Podfile:

      cd <path-to-project>
      
    3. Uruchom polecenie instalacji poda. Spowoduje to zainstalowanie interfejsów API określonych w pliku Podfile wraz ze wszystkimi ich zależnościami.

      pod install
      
    4. Zamknij Xcode, a następnie otwórz (kliknij dwukrotnie) plik .xcworkspace swojego projektu, aby uruchomić Xcode. Od tej pory do otwierania projektu musisz używać pliku .xcworkspace.

    Instalowanie XCFramework

    Pobierz plik binarny i zasoby pakietu SDK:

    XCFramework to pakiet binarny używany do instalowania Driver SDK. Możesz korzystać z tego pakietu na wielu platformach, w tym na komputerach z chipsetem M1. Z tego przewodnika dowiesz się, jak ręcznie dodać do projektu środowisko XCFramework z pakietem Driver SDK i skonfigurować ustawienia kompilacji w Xcode.

    1. Rozpakuj skompresowane pliki, aby uzyskać dostęp do XCFramework i zasobów.

    2. Uruchom Xcode i otwórz istniejący projekt lub utwórz nowy. Jeśli dopiero zaczynasz korzystać z systemu iOS, utwórz nowy projekt i wybierz szablon aplikacji na iOS.

    3. Utwórz w grupie projektów grupę z platformami, jeśli jeszcze takiej nie ma.

    4. Przeciągnij pobrany plik gRPCCertificates.bundle do katalogu najwyższego poziomu w projekcie Xcode. Gdy pojawi się odpowiedni komunikat, wybierz Kopiuj elementy.

    5. Aby zainstalować pakiet Driver SDK, przeciągnij plik GoogleRidesharingDriver.xcframework do swojego projektu w obszarze Frameworks, Library, and Embedded Content. Gdy pojawi się odpowiedni komunikat, wybierz Kopiuj elementy.

    6. Przeciągnij pobrany plik GoogleRidesharingDriver.bundle do katalogu najwyższego poziomu w projekcie Xcode. Gdy pojawi się odpowiedni komunikat, wybierz Copy items if needed.

    7. Wybierz projekt w narzędziu Project Navigator, a następnie wskaż środowisko docelowe aplikacji.

    8. Otwórz kartę Etapy kompilacji i w sekcji Połącz plik binarny z bibliotekami dodaj te platformy i biblioteki, jeśli jeszcze ich nie ma:

      • 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
    9. Wybierz projekt zamiast konkretnego miejsca docelowego i otwórz kartę Ustawienia kompilacji. W sekcji Inne flagi łączące dodaj ‑ObjC na potrzeby debugowania i wersji. Jeśli te ustawienia nie są widoczne, zmień filtr na pasku ustawień kompilacji z Podstawowe na Wszystkie.

    Wersje pakietu SDK alfa i beta

    Aby skonfigurować wersję alfa lub beta pakietu Driver SDK na iOS, potrzebujesz tych elementów:

    • Narzędzie CocoaPods: aby zainstalować to narzędzie, otwórz Terminal i uruchom następujące polecenie.

      sudo gem install cocoapods
      

      Więcej informacji znajdziesz w wprowadzeniu do CocoaPods.

    • Twoje konto dewelopera na liście dostępu Google. Repozytorium podów pakietu SDK w wersjach alfa i beta nie jest źródłem publicznym. Aby uzyskać do nich dostęp, skontaktuj się z inżynierem ds. obsługi klienta Google. Inżynier dodaje Twoje konto programistyczne do listy dostępu, a następnie ustawia plik cookie do uwierzytelniania.

    Gdy projekt znajdzie się na liście dostępu, uzyskasz do niego dostęp.

    1. Utwórz plik Podfile dla pakietu Driver SDK na iOS i użyj go do zainstalowania interfejsu API i jego zależności: utwórz plik o nazwie Podfile w katalogu projektu. Ten plik definiuje zależności projektu. Edytuj plik Podfile i dodaj zależności. Oto przykład, który zawiera zależności:

      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
      
    2. Zapisz plik Podfile. Otwórz terminal i przejdź do katalogu zawierającego plik Podfile:

      cd <path-to-project>
      
    3. Uruchom polecenie instalacji poda. To polecenie instaluje interfejsy API określone w pliku Podfile wraz ze wszystkimi ich zależnościami.

      pod install
      
    4. Zamknij Xcode, a następnie otwórz (kliknij dwukrotnie) plik .xcworkspace swojego projektu, aby uruchomić Xcode. Od tej pory do otwierania projektu musisz używać pliku .xcworkspace.

    Wdrażanie autoryzacji i uwierzytelniania

    Gdy aplikacja Driver generuje i wysyła aktualizacje do backendu Fleet Engine, żądania muszą zawierać prawidłowe tokeny dostępu. Aby autoryzować i uwierzytelnić te żądania, pakiet Driver SDK wywołuje Twój obiekt zgodny z protokołem GMTDAuthorization. Obiekt odpowiada za udostępnienie wymaganego tokena dostępu.

    Jako deweloper aplikacji możesz wybrać sposób generowania tokenów. Implementacja powinna umożliwiać Ci:

    • Pobierz token dostępu, prawdopodobnie w formacie JSON, z serwera HTTPS.
    • Przeanalizuj token i zapisz go w pamięci podręcznej.
    • Odśwież token po jego wygaśnięciu.

    Szczegółowe informacje o tokenach oczekiwanych przez serwer Fleet Engine znajdziesz w artykule Tworzenie tokena internetowego JSON (JWT) na potrzeby autoryzacji.

    Identyfikator dostawcy jest taki sam jak identyfikator projektu Google Cloud. Więcej informacji znajdziesz w przewodniku użytkownika interfejsu Fleet Engine Deliveries API.

    Poniższy przykład implementuje dostawcę tokena dostępu:

    #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
    

    Tworzenie instancji DeliveryDriverAPI

    Aby uzyskać instancję GMTDDeliveryVehicleReporter, musisz najpierw utworzyć instancję GMTDDeliveryDriverAPI przy użyciu interfejsów providerID, vehicleID, driverContext i accessTokenProvider. Identyfikator providerID jest taki sam jak identyfikator projektu Google Cloud. Masz też dostęp do instancji GMTDDeliveryVehicleReporter bezpośrednio przez interfejs API sterownika.

    Ten przykład tworzy instancję 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];
    }
    

    Opcjonalnie możesz nasłuchiwać zdarzeń VehicleReporter

    GMTDDeliveryVehicleReporter okresowo aktualizuje pojazd, gdy locationTrackingEnabled ma wartość TAK. Aby reagować na te okresowe aktualizacje, każdy obiekt może subskrybować zdarzenia GMTDDeliveryVehicleReporter, spełniając wymagania protokołu GMTDVehicleReporterListener.

    Możesz obsługiwać te zdarzenia:

    • vehicleReporter:didSucceedVehicleUpdate

      Informuje aplikację sterownika, że usługi backendu odebrały aktualizację lokalizacji i stanu pojazdu.

    • vehicleReporter:didFailVehicleUpdate:withError

      Informują detektora o niepowodzeniu aktualizacji pojazdu. Dopóki śledzenie lokalizacji jest włączone, GMTDDeliveryVehicleReporter wysyła najnowsze dane do backendu Fleet Engine.

    Ten przykład obsługuje te zdarzenia:

    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
    

    Włącz śledzenie lokalizacji

    Aby włączyć śledzenie lokalizacji, Twoja aplikacja może ustawić wartość YES na locationTrackingEnabled na urządzeniu GMTDDeliveryVehicleReporter. Następnie GMTDDeliveryVehicleReporter automatycznie wysyła aktualizacje lokalizacji. Gdy GMSNavigator jest w trybie nawigacji (gdy miejsce docelowe jest ustawione przez setDestinations), a locationTrackingEnabled ma wartość YES, GMTDDeliveryVehicleReporter też automatycznie wysyła informacje o trasie i szacowanym czasie dotarcia.

    Trasa ustawiona podczas aktualizacji to ta sama trasa, którą kieruje kierowca podczas sesji nawigacji. Dlatego, aby śledzenie floty działało prawidłowo, punkt pośredni ustawiony w -setDestinations:callback: powinien być zgodny z miejscem docelowym w backendzie Fleet Engine.

    Poniższy przykład umożliwia włączenie śledzenia lokalizacji:

    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
    

    Domyślny interwał raportowania wynosi 10 sekund, ale można go zmienić za pomocą funkcji locationUpdateInterval. Minimalny obsługiwany odstęp czasu aktualizacji to 5 sekund. Maksymalny obsługiwany interwał aktualizacji to 60 sekund. Częstsze aktualizacje mogą powodować wolniejsze wykonywanie żądań i błędy.

    Wyłącz aktualizacje lokalizacji i włącz pojazd offline

    Aplikacja może wyłączyć aktualizacje lokalizacji pojazdu. Na przykład po zakończeniu zmiany kierowcy aplikacja może ustawić właściwość locationTrackingEnabled na NO.

      _vehicleReporter.locationTrackingEnabled = NO