인앱 업데이트 지원(Unity)

이 가이드에서는 Unity를 사용하여 앱에서 인앱 업데이트를 지원하는 방법을 설명합니다. Kotlin 프로그래밍 언어나 Java 프로그래밍 언어를 사용하는 구현의 경우와 네이티브 코드(C/C++)를 사용하는 구현의 경우에 따라 가이드가 다릅니다.

개발 환경 설정

Unity용 Google 패키지에서 최신 버전의 Play In-App Update Unity 플러그인을 다운로드합니다.

Unity SDK 개요

Play In-App Update API는 Play Core SDK 제품군의 일부입니다. Unity 플러그인은 앱과 Play API 간 통신을 처리하는 AppUpdateManager 클래스를 제공합니다. 이 클래스를 사용하여 인앱 업데이트를 관리하려면 먼저 클래스를 인스턴스화해야 합니다.

AppUpdateManager appUpdateManager = new AppUpdateManager();

업데이트 사용 가능 여부 확인

업데이트를 요청하기 전에 앱에 사용할 수 있는 업데이트가 있는지 확인합니다. AppUpdateManager를 사용하여 코루틴의 업데이트가 있는지 확인합니다.

IEnumerator CheckForUpdate()
{
  PlayAsyncOperation<AppUpdateInfo, AppUpdateErrorCode> appUpdateInfoOperation =
    appUpdateManager.GetAppUpdateInfo();

  // Wait until the asynchronous operation completes.
  yield return appUpdateInfoOperation;

  if (appUpdateInfoOperation.IsSuccessful)
  {
    var appUpdateInfoResult = appUpdateInfoOperation.GetResult();
    // Check AppUpdateInfo's UpdateAvailability, UpdatePriority,
    // IsUpdateTypeAllowed(), etc. and decide whether to ask the user
    // to start an in-app update.
  }
  else
  {
    // Log appUpdateInfoOperation.Error.
  }
}

반환된 AppUpdateInfo 인스턴스에는 업데이트 사용 가능 여부 상태가 포함되어 있습니다. 인앱 업데이트가 이미 진행 중이면 인스턴스는 진행 중인 업데이트의 상태도 보고합니다.

업데이트 비활성화 확인

업데이트 사용 가능 여부를 확인하는 것 외에 Play 스토어를 통해 사용자에게 업데이트 알림이 전송된 후 얼마나 시간이 지났는지 확인하는 것도 좋습니다. 그렇게 하면 유연한 업데이트를 시작할지 아니면 즉시 업데이트를 시작할지 판단하는 데 도움이 될 수 있습니다. 예를 들어 며칠을 기다렸다가 사용자에게 유연한 업데이트를 알린 다음 며칠 후 즉시 업데이트를 요청할 수도 있습니다.

Play 스토어를 통해 업데이트가 제공된 후 경과한 일수를 확인하려면 ClientVersionStalenessDays를 사용합니다.

var stalenessDays = appUpdateInfoOperation.ClientVersionStalenessDays;

업데이트 우선순위 확인

Google Play Developer API를 사용하여 각 업데이트의 우선순위를 설정할 수 있습니다. 이렇게 하면 앱에서 사용자에게 업데이트를 얼마나 강력하게 권장할지 결정할 수 있습니다. 업데이트 우선순위를 설정하는 다음 전략을 예로 들어 보겠습니다.

  • 사소한 UI 개선: 낮은 우선순위 업데이트. 유연한 업데이트와 즉시 업데이트를 둘 다 요청하지 않습니다.
  • 성능 개선: 중간 우선순위 업데이트. 유연한 업데이트를 요청합니다.
  • 중요 보안 업데이트: 높은 우선순위 업데이트. 즉시 업데이트를 요청합니다.

우선순위를 결정하기 위해 Google Play는 0에서 5 사이의 정숫값을 사용하며 0은 기본값, 5는 가장 높은 우선순위를 나타냅니다. 업데이트 우선순위를 설정하려면 Google Play Developer API의 Edits.tracks.releases 아래에 있는 inAppUpdatePriority 필드를 사용하세요. 출시에 새로 추가된 모든 버전은 출시와 동일한 우선순위로 간주됩니다. 우선순위는 새 버전을 출시할 때만 설정할 수 있으며 나중에 변경할 수 없습니다.

Play Developer API 문서에 설명된 대로 Google Play Developer API를 사용하여 우선순위를 설정합니다. 인앱 업데이트 우선순위는 Edit.tracks: update 메서드에 전달된 Edit.tracks 리소스에서 지정해야 합니다. 다음 예는 버전 코드가 88이고 inAppUpdatePriority가 5인 앱 출시를 보여 줍니다.

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

앱 코드에서 UpdatePriority를 사용하여 특정 업데이트의 우선순위를 확인할 수 있습니다.

var priority = appUpdateInfoOperation.UpdatePriority;

업데이트 시작

업데이트를 사용할 수 있는지 확인한 후 AppUpdateManager.StartUpdate()를 사용하여 업데이트를 요청하면 됩니다. 업데이트를 요청하기 전에 최신 AppUpdateInfo 객체가 있는지 확인합니다. AppUpdateOptions 객체도 만들어 업데이트 흐름을 구성해야 합니다.

다음은 즉시 업데이트 흐름을 위한 AppUpdateOptions 객체 생성의 예입니다.

// Creates an AppUpdateOptions defining an immediate in-app
// update flow and its parameters.
var appUpdateOptions = AppUpdateOptions.ImmediateAppUpdateOptions();

다음은 유연한 업데이트 흐름을 위한 AppUpdateOptions 객체 생성의 예입니다.

// Creates an AppUpdateOptions defining a flexible in-app
// update flow and its parameters.
var appUpdateOptions = AppUpdateOptions.FlexibleAppUpdateOptions();

AppUpdateOptions 객체에는 기기 저장용량이 제한된 경우 업데이트가 애셋 팩을 지울 수 있는지를 정의하는 AllowAssetPackDeletion 필드도 포함되어 있습니다. 이 필드는 기본적으로 false로 설정되지만 allowAssetPackDeletion 선택적 인수를 ImmediateAppUpdateOptions()FlexibleAppUpdateOptions()에 전달하여 true로 대신 설정할 수 있습니다.

// Creates an AppUpdateOptions for an immediate flow that allows
// asset pack deletion.
var appUpdateOptions =
  AppUpdateOptions.ImmediateAppUpdateOptions(allowAssetPackDeletion: true);

// Creates an AppUpdateOptions for a flexible flow that allows asset
// pack deletion.
var appUpdateOptions =
  AppUpdateOptions.FlexibleAppUpdateOptions(allowAssetPackDeletion: true);

다음 단계는 유연한 업데이트즉시 업데이트 중 무엇을 요청하는지에 따라 다릅니다.

유연한 업데이트 처리

최신 AppUpdateInfo 객체와 올바르게 구성된 AppUpdateOptions 객체를 확보한 후 AppUpdateManager.StartUpdate()를 호출하여 비동기식으로 업데이트 흐름을 요청할 수 있습니다.

IEnumerator StartFlexibleUpdate()
{
  // Creates an AppUpdateRequest that can be used to monitor the
  // requested in-app update flow.
  var startUpdateRequest = appUpdateManager.StartUpdate(
    // The result returned by PlayAsyncOperation.GetResult().
    appUpdateInfoResult,
    // The AppUpdateOptions created defining the requested in-app update
    // and its parameters.
    appUpdateOptions);

  while (!startUpdateRequest.IsDone)
  {
  // For flexible flow,the user can continue to use the app while
  // the update downloads in the background. You can implement a
  // progress bar showing the download status during this time.
  yield return null;
  }

}

유연한 업데이트 흐름의 경우에는 다운로드가 성공적으로 완료된 후 앱 업데이트 설치를 트리거해야 합니다. 이렇게 하려면 다음 예와 같이 AppUpdateManager.CompleteUpdate()를 호출합니다.

IEnumerator CompleteFlexibleUpdate()
{
  var result = appUpdateManager.CompleteUpdate();
  yield return result;

  // If the update completes successfully, then the app restarts and this line
  // is never reached. If this line is reached, then handle the failure (e.g. by
  // logging result.Error or by displaying a message to the user).
}

즉시 업데이트 처리

최신 AppUpdateInfo 객체와 올바르게 구성된 AppUpdateOptions 객체를 확보한 후 AppUpdateManager.StartUpdate()를 호출하여 비동기식으로 업데이트 흐름을 요청할 수 있습니다.

IEnumerator StartImmediateUpdate()
{
  // Creates an AppUpdateRequest that can be used to monitor the
  // requested in-app update flow.
  var startUpdateRequest = appUpdateManager.StartUpdate(
    // The result returned by PlayAsyncOperation.GetResult().
    appUpdateInfoResult,
    // The AppUpdateOptions created defining the requested in-app update
    // and its parameters.
    appUpdateOptions);
  yield return startUpdateRequest;

  // If the update completes successfully, then the app restarts and this line
  // is never reached. If this line is reached, then handle the failure (for
  // example, by logging result.Error or by displaying a message to the user).
}

즉시 업데이트 흐름의 경우에는 Google Play에 사용자 확인 대화상자가 표시됩니다. 사용자가 요청을 수락하면 Google Play에서 업데이트를 자동으로 다운로드하고 설치한 다음 설치가 완료되면 앱을 업데이트된 버전으로 다시 시작합니다.

오류 처리

이 섹션에서는 일반적인 오류 해결 방법을 설명합니다.

  • StartUpdate()에서 ArgumentNullException이 발생한다면 AppUpdateInfo가 null인 것입니다. 업데이트 흐름을 시작하기 전에 GetAppUpdateInfo()에서 반환된 AppUpdateInfo 객체가 null이 아닌지 확인합니다.
  • PlayAsyncOperationErrorUpdateUnavailable 오류 코드를 반환한다면 동일한 애플리케이션 ID와 서명 키가 있는 업데이트된 앱 버전을 사용할 수 있는지 확인합니다.
  • PlayAsyncOperationErrorUpdateNotAllowed 오류 코드를 반환한다면 AppUpdateOptions 객체가 사용 가능 업데이트에 허용되지 않은 업데이트 유형을 나타냄을 의미합니다. 업데이트 흐름을 시작하기 전에 선택된 업데이트 유형이 허용되는 것으로 AppUpdateInfo 객체에 나타나는지 확인합니다.

다음 단계

앱의 인앱 업데이트를 테스트하여 통합이 올바르게 작동하는지 확인합니다.