Obsługa aktualizacji w aplikacji (Unreal Engine)

Ten przewodnik wyjaśnia, jak obsługiwać aktualizacje w aplikacji w aplikacji za pomocą Unreal Engine. Istnieją osobne przewodniki na wypadek, gdy Twoja implementacja korzysta z języka programowania Kotlin lub Java, a także w przypadku, gdy korzysta z kodu natywnego (C/C++) lub Unity.

Omówienie pakietu Unreal Engine SDK

Interfejs Play In-App Updates API należy do rodziny pakietów SDK Play Core. Interfejs API Unreal Engine udostępnia klasę UInAppUpdatesManager, która umożliwia komunikację między aplikacją a interfejsem Play API. Po wysłaniu żądania aplikacja może sprawdzić jego stan za pomocą EAppUpdateErrorCode.

Obsługiwane wersje Unreal Engine

Wtyczka obsługuje Unreal Engine 5.0 i wszystkie kolejne wersje.

Konfigurowanie środowiska programistycznego

  1. Pobierz wtyczkę Play do Unreal Engine z repozytorium GitHub.

  2. Skopiuj folder GooglePlay w folderze Plugins w projekcie Unreal Engine.

  3. Otwórz projekt Unreal Engine i kliknij Edytuj → Wtyczki.

  4. Wyszukaj Google Play i zaznacz pole wyboru Włączone.

  5. Ponownie uruchom projekt gry i utwórz wersję.

  6. Otwórz plik Build.cs projektu i dodaj moduł PlayInAppUpdates do pliku PublicDependencyModuleNames:

    using UnrealBuildTool;
    
    public class MyGame : ModuleRules
    {
      public MyGame(ReadOnlyTargetRules Target) : base(Target)
      {
        // ...
    
        PublicDependencyModuleNames.Add("PlayInAppUpdates");
    
        // ...
      }
    }
    

Sprawdzanie dostępności aktualizacji

Zanim poprosisz o aktualizację, sprawdź, czy jest dostępna aktualizacja aplikacji. Aby to zrobić, kliknij UInAppUpdatesManager::RequestInfo:

MyClass.h

void MyClass::OnRequestInfoOperationCompleted(
  EAppUpdateErrorCode ErrorCode,
  UAppUpdateInfo* UpdateInfo)
{
  // Check the resulting error code.
  if (ErrorCode == EAppUpdateErrorCode::AppUpdate_NO_ERROR)
  {
    // Check AppUpdateInfo's UpdateAvailability, UpdatePriority,
    // IsUpdateTypeAllowed(), ... and decide whether to ask the user
    // to start an in-app update.
  }
}

MyClass.cpp

void MyClass::CheckForUpdateAvailability()
{
  // Create a delegate to bind the callback function.
  FRequestInfoOperationCompletedDelegate Delegate;

  // Bind the completion handler (OnRequestInfoOperationCompleted) to the delegate.
  Delegate.BindDynamic(this, &MyClass::OnRequestInfoOperationCompleted);

  // Initiate the request info operation, passing the delegate to handle the result.
  GetGameInstance()
    ->GetSubsystem<UInAppUpdatesManager>()
    ->RequestInfo(Delegate);
}

Zwrócona instancja UAppUpdateInfo zawiera stan dostępności aktualizacji. Jeśli trwa aktualizacja aplikacji, instancja podaje też stan tej aktualizacji.

Sprawdzanie aktualności aktualizacji

Oprócz sprawdzenia, czy jest dostępna aktualizacja, warto też sprawdzić, ile czasu minęło od ostatniego powiadomienia o aktualizacji w Sklepie Play. Pomoże Ci to zdecydować, czy chcesz przeprowadzić elastyczne, czy natychmiastowe wprowadzenie zmian. Możesz na przykład poczekać kilka dni, zanim powiadomisz użytkownika o możliwości aktualizacji, a potem jeszcze kilka dni, zanim poprosisz o natychmiastową aktualizację.

Aby sprawdzić, ile dni minęło od udostępnienia aktualizacji w Sklepie Play, użyj UAppUpdateInfo:GetClientVersionStalenessDays:

int32 ClientVersionStalenessDays = UpdateInfo->GetClientVersionStalenessDays();

Sprawdzanie priorytetu aktualizacji

Interfejs Google Play Developer API umożliwia ustawienie priorytetu każdej aktualizacji. Pozwala to aplikacji określić, jak mocno zalecić użytkownikowi zaktualizowanie aplikacji. Rozważ na przykład tę strategię ustawiania priorytetu aktualizacji:

  • Niewielkie ulepszenia interfejsu: aktualizacja o niskim priorytecie; prośba o nieelastyczne ani natychmiastowe wdrożenie.
  • Ulepszenia dotyczące wydajności: aktualizacja o średnim priorytecie; poproś o elastyczne aktualizacje.
  • Niezbędna aktualizacja zabezpieczeń: wysoki priorytet; zalecana natychmiastowa aktualizacja.

Aby określić priorytet, Google Play używa liczby całkowitej z zakresu od 0 do 5, gdzie 0 to domyślny priorytet, a 5 – najwyższy priorytet. Aby ustawić priorytet aktualizacji, użyj pola inAppUpdatePriority w sekcji Edits.tracks.releases w interfejsie Google Play Developer API. Wszystkie nowo dodane wersje w ramach danej wersji mają ten sam priorytet. Priorytet można ustawić tylko podczas wdrażania nowej wersji i nie można go później zmienić.

Ustaw priorytet za pomocą interfejsu Google Play Developer API zgodnie z opisem w dokumentacji Play Developer API. Priorytet aktualizacji w aplikacji powinien być określony w zasobie Edit.tracks przekazanym w ramach metody Edit.tracks: update. Ten przykład pokazuje, jak opublikować aplikację z kodem wersji 88 i inAppUpdatePriority 5:

{
  "releases": [{
      "versionCodes": ["88"],
      "inAppUpdatePriority": 5,
      "status": "completed"
  }]
}

W kodzie aplikacji możesz sprawdzić poziom priorytetu danej aktualizacji za pomocą: UAppUpdateInfo::UpdatePriority:

int32 Priority = UpdateInfo->GetPriority();

Rozpoczynanie aktualizacji

Po potwierdzeniu dostępności aktualizacji możesz poprosić o jej zainstalowanie za pomocą opcji UInAppUpdatesManager::StartUpdate. Zanim poprosisz o aktualizację, upewnij się, że masz aktualny obiekt UAppUpdateInfo. Aby skonfigurować proces aktualizacji, musisz też utworzyć obiekt UAppUpdateOptions.

W tym przykładzie tworzymy obiekt UAppUpdateOptions do natychmiastowego procesu aktualizacji:

// Creates an UAppUpdateOptions defining an immediate in-app
// update flow and its parameters.
UAppUpdateOptions* Options = NewObject<UAppUpdateOptions>();
Options->CreateOptions(EAppUpdateType::AppUpdate_TYPE_IMMEDIATE);

W tym przykładzie tworzymy obiekt UAppUpdateOptions w ramach elastycznego procesu aktualizacji:

// Creates an UAppUpdateOptions defining a flexible in-app
// update flow and its parameters.
UAppUpdateOptions* Options = NewObject<UAppUpdateOptions>();
Options->CreateOptions(EAppUpdateType::AppUpdate_TYPE_FLEXIBLE);

Obiekt UAppUpdateOptions zawiera też funkcję IsAssetPackDeletionAllowed, która zwraca informację, czy aktualizacja może wyczyścić pakiety zasobów w przypadku ograniczonej ilości miejsca na urządzeniu. To pole ma domyślnie wartość false, ale możesz ustawić je za pomocą UAppUpdateOptions::SetAssetPackDeletionAllowed, aby zamiast tego przypisać mu wartość true:

// Sets the AssetPackDeletionAllowed field to true.
Options->SetAssetPackDeletionAllowed(true);

Kolejne kroki zależą od tego, czy prośba dotyczy elastycznej aktualizacji, czy natychmiastowej aktualizacji.

Obsługa elastycznej aktualizacji

Gdy masz aktualny obiekt UAppUpdateInfo i prawidłowo skonfigurowany obiekt UAppUpdateOptions, możesz wywołać funkcję UInAppUpdatesManager::StartUpdate, aby poprosić o przeprowadzenie procesu aktualizacji.

MyClass.h

void MyClass::OnStartUpdateOperationCompleted(EAppUpdateErrorCode ErrorCode)
{
  // ...
}

MyClass.cpp

// .cpp
void MyClass::StartUpdate()
{
  // Create a delegate to bind the callback function.
  FUpdateOperationCompletedDelegate Delegate;

  // Bind the completion handler (OnStartUpdateOperationCompleted) to the delegate.
  Delegate.BindDynamic(this, &MyClass::OnStartUpdateOperationCompleted);

  // Initiate the start update operation, passing the delegate to handle the result.
  GetGameInstance()
    ->GetSubsystem<UInAppUpdatesManager>()
    ->StartUpdate(UpdateInfo, UpdateOptions, Delegate);
}

Aby umożliwić elastyczny proces aktualizacji, musisz wywołać instalację aktualizacji aplikacji po pomyślnym pobraniu. W tym celu wywołaj funkcję InAppUpdatesManager::CompleteUpdate, jak w tym przykładzie:

MyClass.h

void MyClass::OnCompleteUpdateOperationCompleted(EAppUpdateErrorCode ErrorCode)
{
  // ...
}

MyClass.cpp

void MyClass::CompleteFlexibleUpdate()
{
  // Create a delegate to bind the callback function.
  FUpdateOperationCompletedDelegate Delegate;

  // Bind the completion handler (OnCompleteUpdateOperationCompleted) to the delegate.
  Delegate.BindDynamic(this, &MyClass::OnCompleteUpdateOperationCompleted);

  // Initiate the complete update operation, passing the delegate to handle the result.
  GetGameInstance()
    ->GetSubsystem<UInAppUpdatesManager>()
    ->CompleteUpdate(UpdateInfo, UpdateOptions, Delegate);
}

Przeprowadzanie natychmiastowej aktualizacji

Gdy masz aktualny obiekt UAppUpdateInfo i prawidłowo skonfigurowany obiekt UAppUpdateOptions, możesz wywołać funkcję InAppUpdatesManager::StartUpdate, aby poprosić o przeprowadzenie procesu aktualizacji.

MyClass.h

void MyClass::OnStartUpdateOperationCompleted(EAppUpdateErrorCode ErrorCode)
{
  // ...
}

MyClass.cpp

void MyClass::StartUpdate()
{
  // Create a delegate to bind the callback function.
  FUpdateOperationCompletedDelegate Delegate;

  // Bind the completion handler (OnStartUpdateOperationCompleted) to the delegate.
  Delegate.BindDynamic(this, &MyClass::OnStartUpdateOperationCompleted);

  // Initiate the start update operation, passing the delegate to handle the result.
  GetGameInstance()
    ->GetSubsystem<UInAppUpdatesManager>()
    ->StartUpdate(UpdateInfo, UpdateOptions, Delegate);
}

W przypadku natychmiastowej aktualizacji Google Play wyświetla użytkownikowi okno potwierdzenia. Gdy użytkownik zaakceptuje prośbę, Google Play automatycznie pobierze i zainstaluje aktualizację, a następnie uruchomi zaktualizowaną wersję aplikacji, jeśli instalacja przebiegnie pomyślnie.

Obsługa błędów

W tej sekcji znajdziesz rozwiązania typowych problemów.

  • Jeśli funkcja UInAppUpdatesManager::StartUpdate zwraca błąd AppUpdate_INVALID_REQUEST, oznacza to, że argument UAppUpdateInfo jest nieprawidłowy. Zanim rozpoczniesz przepływ aktualizacji, sprawdź, czy obiekt UAppUpdateInfo zwrócony przez funkcję UInAppUpdatesManager::RequestInfo nie jest pusty.
  • Jeśli UInAppUpdatesManager::StartUpdate zwróci błąd AppUpdate_NOT_ALLOWED, oznacza to, że obiekt UAppUpdateOptions wskazuje typ aktualizacji, który nie jest dozwolony dla dostępnej aktualizacji. Przed rozpoczęciem procesu aktualizacji sprawdź, czy obiekt UAppUpdateInfo wskazuje, że wybrany typ aktualizacji jest dozwolony.

Dalsze kroki

Przetestuj aktualizacje w aplikacji, aby sprawdzić, czy integracja działa prawidłowo.