Pierwsze kroki z pakietem SDK Driver na iOS

Pakiet Driver SDK to biblioteka zintegrowana z aplikacją sterownika. Jest odpowiada za aktualizację Fleet Engine o lokalizację kierowcy, trasę pozostały dystans i szacowany czas dotarcia na miejsce. Dodatkowo integruje się z pakietem SDK Navigation, który udostępnia kierowcy szczegółowe wskazówki dojazdu.

Minimalne wymagania systemowe

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

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

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

    Uzyskaj dostęp

    Jeśli jesteś klientem Google Workspace, utwórz Grupa Workspace, na przykład google-maps-platform-sdk-users@workspacedomain.com podczas wprowadzenia oraz podać imię i nazwisko firmie Google. To zalecane podejście. Twoja grupa Workspace zostanie dodana do listy dozwolonych, która przyznaje dostęp do prawidłowych repozytoriów CocoaPods. Upewnij się, że użytkownik adresy e-mail oraz adresy e-mail kont usługi, które potrzebują dostępu, są uwzględnione na tej liście.

    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óre potrzebują dostępu do tych artefaktów.

    Programowanie lokalne

    W przypadku programowania lokalnego wystarczy zalogować się za pomocą Pakiet 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 z sprawdzone metody:

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

    • W przeciwnym razie zapisz plik klucza konta usługi w bezpiecznej lokalizacji systemu plików hosta i ustaw parametr GOOGLE_APPLICATION_CREDENTIALS odpowiednio zmiennej środowiskowej.

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

    Konfiguracja projektu

    Pakiet Driver SDK możesz skonfigurować za pomocą CocoaPods.

    Używaj CocoaPods

    Aby skonfigurować pakiet Driver SDK za pomocą CocoaPods, potrzebujesz tych elementów:

    • Narzędzie CocoaPods: aby zainstalować to narzędzie, otwórz Terminal i uruchom tego polecenia. shell sudo gem install cocoapods Zapoznaj się z Wprowadzenie do CocoaPods .
    1. Utwórz plik Podfile dla pakietu Driver SDK i użyj go do zainstalowania Interfejs API i jego zależności: utwórz w projekcie plik o nazwie Podfile katalogu. Ten plik definiuje zależności projektu. Edytuj plik Podfile i dodaj zależności. Oto przykład, który zawiera parametr 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 Pod:

      cd <path-to-project>
      
    3. Uruchom polecenie instalacji poda. Spowoduje to zainstalowanie interfejsów API określonych w Podfile wraz z ewentualnymi 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 musisz używać pliku .xcworkspace aby otworzyć projekt.

    Wersje pakietu SDK alfa i beta

    Aby skonfigurować wersję alfa lub beta pakietu Driver SDK na iOS, musisz mieć następujące elementy:

    • Narzędzie CocoaPods: aby zainstalować to narzędzie, otwórz Terminal i uruchom tego polecenia.

      sudo gem install cocoapods
      

      Zapoznaj się z Wprowadzenie do CocoaPods .

    • Twoje konto dewelopera na liście dostępu Google. Repozytorium podów wersji alfa i beta pakietu SDK nie są źródłem publicznym. Do uzyskać do nich dostęp, skontaktuj się z inżynierem ds. obsługi klienta Google. Inżynier doda Twoje konto programisty do listy dostępu, a następnie ustawia plik cookie dla uwierzytelnianie.

    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 Interfejs API i jego zależności: utwórz w projekcie plik o nazwie Podfile katalogu. Ten plik definiuje zależności projektu. Edytuj plik Podfile i dodaj zależności. Oto przykład, który zawiera parametr 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 Pod:

      cd <path-to-project>
      
    3. Uruchom polecenie instalacji poda. Spowoduje to zainstalowanie interfejsów API określonych w Podfile wraz z ewentualnymi 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 musisz używać pliku .xcworkspace aby otworzyć projekt.

    Instalowanie XCFramework

    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.

    Pobierz plik binarny i zasoby pakietu SDK:

    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 wybierz miejsce 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.

    Sprawdź plik manifestu prywatności Apple

    Apple wymaga podania informacji o ochronie prywatności w aplikacjach z App Store. Aktualizacje i inne informacje znajdziesz na stronie z informacjami o ochronie prywatności w Apple App Store.

    Plik manifestu prywatności Apple jest zawarty w pakiecie zasobów SDK. Aby sprawdzić, czy plik manifestu prywatności został dołączony, i sprawdzić jego zawartość, utwórz archiwum aplikacji i wygeneruj raport o ochronie prywatności z archiwum.

    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 uwierzytelniają te żądania, pakiet Driver SDK wywołuje obiekt zgodny z GMTDAuthorization protokołu. Obiekt odpowiada za udostępnienie wymaganego tokena dostępu.

    Jako deweloper aplikacji możesz wybrać sposób generowania tokenów. Twoja implementacja powinien umożliwiać:

    • 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 sekcji Tworzenie tokena internetowego JSON (JWT) na potrzeby autoryzacji

    Identyfikator dostawcy jest taki sam jak identyfikator projektu Google Cloud. Zobacz Przewodnik 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ć instancji GMTDDeliveryDriverAPI za pomocą identyfikatora dostawcy, pojazdID, driveContext i accessTokenProvider. Identyfikator dostawcy jest taki sam jak Identyfikator projektu Google Cloud. Możesz też uzyskać dostęp do usługi GMTDDeliveryVehicleReporter bezpośrednio z interfejsu 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 – TAK. W odpowiedzi na te okresowe aktualizacje obiekt może subskrybować zdarzenia GMTDDeliveryVehicleReporter przez dostosowanie protokół GMTDVehicleReporterListener.

    Możesz obsługiwać te zdarzenia:

    • vehicleReporter:didSucceedVehicleUpdate

      Informuje aplikację sterownika, że usługi backendu otrzymały informacje o lokalizacji i stanie pojazdu.

    • vehicleReporter:didFailVehicleUpdate:withError

      Informują detektora o niepowodzeniu aktualizacji pojazdu. Dopóki lokalizacja śledzenie jest włączone, GMTDDeliveryVehicleReporter 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ć wartość YES na locationTrackingEnabled w aplikacji GMTDDeliveryVehicleReporter. Zatem GMTDDeliveryVehicleReporter = automatycznie wysyłać aktualizacje lokalizacji. Gdy GMSNavigator jest w trakcie nawigacji (gdy miejsce docelowe jest ustawione za pomocą setDestinations) i Ustawienie locationTrackingEnabled ma wartość YES. GMTDDeliveryVehicleReporter będzie automatycznie wysyłać aktualne informacje o trasie i szacowanym czasie dotarcia na miejsce.

    Trasa ustawiona podczas aktualizacji będzie taka sama, jak trasa kierowcy przejście do adresu podczas sesji nawigacji. Dzięki temu śledzenie przesyłek działa punkt pośredni ustawiony przez -setDestinations:callback: powinien być taki sam jak miejsce docelowe ustawione 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 to 10 sekund, ale interwał raportowania może zostanie zmieniony przez locationUpdateInterval. Minimalny obsługiwany interwał aktualizacji wynosi 5 sekund. Maksymalny obsługiwany interwał aktualizacji to 60 sekund. Częściej mogą spowalniać przesyłanie żądań i błędów.

    Wyłącz aktualizacje lokalizacji

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

      _vehicleReporter.locationTrackingEnabled = NO
    

    Obsługa błędów update_mask

    Gdy GMTDDeliveryVehicleReporter wysyła aktualizację pojazdu, update_mask może wystąpić, gdy maska jest pusta. Zwykle występuje przy pierwszym jego aktualizacja po uruchomieniu. Poniższy przykład pokazuje, jak naprawić ten błąd:

    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