アプリ内アップデートをサポートする(Unity)

このガイドでは、Unity を使用してアプリ内でアプリ内アップデートをサポートする方法について説明します。実装に Kotlin プログラミング言語または Java プログラミング言語を使用するケースと、ネイティブ コード(C / C++)を使用するケースについては、個別のガイドが用意されています。

開発環境をセットアップする

Play のアプリ内アップデートの最新リリースを Unity 用の Google パッケージからダウンロードします。

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 インスタンスには、アップデートの有無を示すステータスが含まれます。アプリ内アップデートがすでに進行中の場合、インスタンスは進行中のアップデートのステータスも報告します。

アップデートの適用から経過した期間を確認する

アップデートが適用可能であるかどうかを確認するだけでなく、ユーザーが Google Play ストアからアップデートの通知を受信してから経過した期間を確認することもできます。これは、フレキシブル アップデートと即時アップデートのどちらを開始する必要があるかを判断する際に有用です。たとえば、ユーザーにフレキシブル アップデートについて通知する前に数日間、および通知を行ってから即時アップデートをリクエストするまでに数日間の猶予期間を設けることができます。

ClientVersionStalenessDays を使用して、Play ストアからのアップデートの入手が可能になった時点から経過した日数を確認します。

var stalenessDays = appUpdateInfoOperation.ClientVersionStalenessDays;

アップデートの優先度を確認する

Google Play Developer API では、各アップデートの優先度を設定できます。 これにより、アプリはユーザーにアップデートを推奨する程度を決定できるようになります。たとえば、アップデートの優先度を設定するための次のような戦略を考えてみます。

  • UI の小さな改善: 優先度が低いアップデート。フレキシブル アップデート、即時アップデートのいずれもリクエストしません。
  • パフォーマンスの改善: 優先度が中程度のアップデート。フレキシブル アップデートをリクエストします。
  • 重要なセキュリティ アップデート: 優先度が高いアップデート。即時アップデートをリクエストします。

優先度を決定するにあたり、Google Play は 0~5 の整数値を使用します。0 はデフォルトの値、5 は優先度が最も高い値です。アップデートの優先度を設定するには、Google Play Developer API の Edits.tracks.releases の下にある inAppUpdatePriority フィールドを使用します。リリースで新たに追加されたすべてのバージョンの優先度は、リリースと同じとみなされます。優先度は新しいリリースの公開時にのみ設定できます。後から変更することはできません。

Google Play Developer API を使用した優先度の設定については、Play Developer API のドキュメントをご覧ください。アプリ内アップデートの優先度は、Edit.tracks: update メソッドで渡される Edit.tracks で指定する必要があります。次の例に、APK(バージョン コード 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 でないことを確認してください。
  • PlayAsyncOperation から ErrorUpdateUnavailable エラーコードが返された場合は、同じアプリケーション ID と署名鍵を持つアプリの更新バージョンが存在することを確認してください。
  • PlayAsyncOperationErrorUpdateNotAllowed エラーコードを返す場合は、AppUpdateOptions オブジェクトが入手可能なアップデートで許可されていないアップデート タイプを示していることを表しています。アップデート フローを開始する前に、選択したアップデート タイプが許可されていることを AppUpdateInfo オブジェクトが示しているかどうかを確認してください。

次のステップ

アプリ内アップデートをテストして、統合が正しく機能していることを確認する。