Pierwsze kroki z pakietem SDK Driver na iOS

Pakiet SDK dla kierowców to biblioteka zintegrowana z aplikacją kierowcy. Odpowiada za aktualizację Fleet Engine o lokalizację pojazdu, trasę, pozostałą odległość i szacowany czas dotarcia. Integruje się też z pakietem Navigation SDK, który dostarcza szczegółowe instrukcje nawigacji dla kierowcy.

Minimalne wymagania systemowe

  • Na urządzeniu mobilnym musi być zainstalowany iOS w wersji 13 lub nowszej.
  • Xcode wersja 14 lub nowsza.
  • Wymagania wstępne

    W tym przewodniku przyjęto założenie, że Twoja aplikacja ma już zaimplementowany pakiet SDK nawigacji oraz że backend Fleet Engine jest skonfigurowany i dostępny. Ten przykładowy kod pokazuje jednak, jak skonfigurować pakiet SDK nawigacji.

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

    Uzyskaj dostęp

    Jeśli jesteś klientem Google Workspace, podczas rejestracji utwórz grupę Workspace, np. 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 zapewnia dostęp do odpowiednich repozytoriów CocoaPods. Upewnij się, że adresy e-mail użytkowników i konta usługi, które potrzebują dostępu, znajdują się na tej liście.

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

    Programowanie lokalne

    W przypadku programowania lokalnego wystarczy zalogować się przy użyciu pakietu SDK Cloud.

    gcloud

    gcloud auth login
    

    Adres e-mail używany do logowania się musi należeć do grupy Workspace.

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

    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 ustaw odpowiednią 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 SDK sterownika na iOS możesz skonfigurować za pomocą Cocoapods lub ręcznie.

    Używanie Cocoapods

    Aby skonfigurować pakiet SDK sterownika na iOS, potrzebujesz tych elementów:

    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 przedstawia 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 Podfile:

      cd <path-to-project>
      
    3. Uruchom polecenie instalacji poda. Spowoduje to zainstalowanie interfejsów API określonych w podfile oraz wszystkich zależności.

      pod install
      
    4. Zamknij Xcode, a następnie kliknij (dwukrotnie) plik .xcworkspace projektu, aby uruchomić Xcode. Od tej pory projekt można otwierać tylko za pomocą pliku .xcworkspace.

    Instalowanie XCFramework

    XCFramework to pakiet binarny służący do instalacji pakietu Driver SDK. Możesz używać tego pakietu na wielu platformach, w tym na maszynach z chipsetem M1. Ten przewodnik pokazuje, jak ręcznie dodać do projektu komponent XCFramework zawierający pakiet SDK Driver i skonfigurować ustawienia kompilacji w Xcode.

    1. Rozpakuj pliki źródłowe otrzymane od Google.

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

    3. Utwórz w grupie projektów grupę Platformy, jeśli jeszcze jej nie ma.

    4. Przeciągnij plik gRPCCertificates.bundle znajdujący się z katalogu Resources w pliku ZIP zawierającym XCFramework do katalogu najwyższego poziomu projektu Xcode. Gdy pojawi się prośba, w razie potrzeby wybierz Kopiuj elementy.

    5. Aby zainstalować pakiet SDK Driver, przeciągnij plik GoogleRidesharingDriver.xcframework do projektu pod Frameworks, Libraries, and Embedded Content. Gdy pojawi się prośba, w razie potrzeby wybierz Kopiuj elementy.

    6. Kliknij prawym przyciskiem myszy GoogleRidesharingDriver.xcframework w projekcie i wybierz Show In Finder.

    7. Przeciągnij GoogleRidesharingDriver.bundle z folderu ios-arm64_x86_64-simulator/GoogleRidesharingDriver.framework/Resources do katalogu najwyższego poziomu projektu Xcode. Gdy pojawi się komunikat, upewnij się, że pole Copy items if needed nie jest zaznaczone.

    8. Wybierz projekt w nawigatorze projektów i wskaż miejsce docelowe aplikacji.

    9. 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
    10. Wybierz projekt, a nie konkretny cel, i otwórz kartę Ustawienia kompilacji. W sekcji Inne oznaczenia łączące dodaj parametr ‑ObjC na potrzeby debugowania i publikowania. 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 to polecenie.

      sudo gem install cocoapods
      

      Więcej informacji znajdziesz w przewodniku dla początkujących na temat CocoaPods.

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

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

    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 przedstawia 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 Podfile:

      cd <path-to-project>
      
    3. Uruchom polecenie instalacji poda. To polecenie instaluje interfejsy API określone w pliku Podfile oraz wszystkie zależności, jakie mogą mieć.

      pod install
      
    4. Zamknij Xcode, a następnie kliknij (dwukrotnie) plik .xcworkspace projektu, aby uruchomić Xcode. Od tej pory projekt można otwierać tylko za pomocą pliku .xcworkspace.

    Wdrażanie autoryzacji i uwierzytelniania

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

    Jako deweloper aplikacji decydujesz o sposobie generowania tokenów. Twoja implementacja powinna pozwalać na:

    • Pobierz token dostępu (na przykład w formacie JSON) z serwera HTTPS.
    • Przeanalizuj token i zapisz go w pamięci podręcznej.
    • Odśwież token, gdy straci ważność.

    Informacje o tokenach oczekiwanych przez serwer Fleet Engine znajdziesz w artykule o tworzeniu tokena internetowego JSON (JWT) do autoryzacji.

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

    W poniższym przykładzie implementowano dostawcę tokenów 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 pobrać instancję GMTDDeliveryVehicleReporter, musisz najpierw utworzyć instancję GMTDDeliveryDriverAPI przy użyciu providerID, vehicleID, driverContext i accessTokenProvider. providerID jest taki sam jak identyfikator projektu Google Cloud. Instancja GMTDDeliveryVehicleReporter jest też dostępna bezpośrednio w interfejsie 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 nasłuchuj zdarzeń VehicleReporter

    GMTDDeliveryVehicleReporter okresowo aktualizuje pojazd, gdy locationTrackingEnabled ma wartość TAK. Aby odpowiedzieć na te okresowe aktualizacje, każdy obiekt może zasubskrybować zdarzenia GMTDDeliveryVehicleReporter, działając zgodnie z protokołem GMTDVehicleReporterListener.

    Możesz obsługiwać te zdarzenia:

    • vehicleReporter:didSucceedVehicleUpdate

      Informuje aplikację sterownika, że usługi backendu pomyślnie otrzymały aktualizację lokalizacji i stanu pojazdu.

    • vehicleReporter:didFailVehicleUpdate:withError

      Informuje detektor o niepowodzeniu aktualizacji pojazdu. Dopóki śledzenie lokalizacji jest włączone, GMTDDeliveryVehicleReporter będzie nadal 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, aplikacja może ustawić locationTrackingEnabled na YES w dniu GMTDDeliveryVehicleReporter. Następnie GMTDDeliveryVehicleReporter automatycznie wysyła aktualne informacje o lokalizacji. Gdy GMSNavigator jest w trybie nawigacji (gdy miejsce docelowe jest ustawione na setDestinations), a locationTrackingEnabled ma wartość YES, GMTDDeliveryVehicleReporter automatycznie wysyła też aktualizacje trasy i szacowanego czasu dotarcia.

    Trasa ustawiona podczas tych aktualizacji jest tą samą trasą, którą pokonuje kierowca podczas sesji nawigacji. Aby śledzenie floty działało prawidłowo, punkt pośredni ustawiony w -setDestinations:callback: powinien być zgodny z miejscem docelowym ustawionym w backendzie Fleet Engine.

    Ten 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ślna długość okresu raportowania wynosi 10 sekund, ale można go zmienić za pomocą funkcji locationUpdateInterval. Minimalny obsługiwany interwał aktualizacji to 5 sekund. Maksymalny obsługiwany interwał aktualizacji to 60 sekund. Częstsze aktualizacje mogą powodować wolniejsze przesyłanie żądań i błędy.

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

    Aplikacja może wyłączyć aktualizacje lokalizacji pojazdu. Na przykład: gdy kończy się zmiana kierowcy, aplikacja może ustawić locationTrackingEnabled na NO.

      _vehicleReporter.locationTrackingEnabled = NO