このガイドでは、Unity を使用してアプリ内でアプリ内アップデートをサポートする方法について説明します。 実装に Kotlin プログラミング言語または Java プログラミング言語 を使用するケースと、実装に ネイティブ コード(C/C++) を使用するケースについては、個別のガイドが用意されています。
Unity SDK の概要
Play In-app Update API は、Play Core SDK ファミリーの一部です。Unity
プラグインには、アプリと Google Play API 間の通信を処理するための AppUpdateManager クラスが用意されています。アプリ内アップデートの管理に使用するには、まずこのクラスをインスタンス化する必要があります。
AppUpdateManager appUpdateManager = new AppUpdateManager();
開発環境を設定する
OpenUPM-CLI
OpenUPM CLI がインストールされている場合は、次のコマンドで OpenUPM レジストリをインストールできます。
openupm add com.google.play.appupdateOpenUPM
[package manager settings] を [Edit > Project Settings > Package Manager] の Unity メニューオプションを選択して開きます。
OpenUPM をスコープ付きレジストリとして [Package Manager] ウィンドウに追加します。
Name: package.openupm.com URL: https://package.openupm.com Scopes: com.google.external-dependency-manager com.google.play.common com.google.play.core com.google.play.appupdateUnity メニュー オプション [Window > Package Manager] を選択して、Package Manager メニューを開きます。
マネージャー スコープのプルダウンで [My Registries](マイレジストリ)を選択します。
パッケージ リストから [Google Play Integrity plugin for Unity] パッケージを選択し、[Install](インストール)を押します。
GitHub からインポート
GitHub から最新の
.unitypackageリリースをダウンロードします。Unity メニュー オプションの [Assets > Import Package > Custom Package] を選択し、すべてのアイテムをインポートして、
.unitypackageファイルをインポートします。
アップデートの有無の確認
アップデートをリクエストする前に、アプリに適用できるアップデートが存在するかどうかを確認します。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(), ... and decide whether to ask the user
// to start an in-app update.
}
else
{
// Log appUpdateInfoOperation.Error.
}
}
返される AppUpdateInfo インスタンスには、アップデートの有無を示す
ステータスが含まれます。アプリ内アップデートがすでに進行中の場合、インスタンスは進行中のアップデートのステータスも報告します。
アップデートの新しさの確認
アップデートが適用可能であるかどうかを確認するだけでなく、ユーザーが Google Play ストアからアップデートの通知を受信してから経過した期間を確認することもできます。これは、フレキシブル アップデートと即時アップデートのどちらを開始したらよいかを判断する際に有用です。たとえば、ユーザーにフレキシブル アップデートを通知するまで数日待ち、その後、即時アップデートを要求するまでさらに数日待つこともできます。
ClientVersionStalenessDays を使用して、Google 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 リソースで渡される Edit.tracks: update
メソッドで指定する必要があります。次の例に、アプリ(バージョン コード 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 であることを示しています。アップデート フローを開始する前に、AppUpdateInfoオブジェクトがGetAppUpdateInfo()から返された null でないことを確認してください。PlayAsyncOperationからErrorUpdateUnavailableエラーコードが返された場合は、同じアプリケーション ID と署名鍵を持つアプリの更新バージョンが存在することを確認してください。PlayAsyncOperationがErrorUpdateNotAllowedエラーコードを返す場合は、AppUpdateOptionsオブジェクトが入手可能なアップデートで許可されていないアップデート タイプを示していることを表しています。アップデート フローを開始する前に、選択したアップデート タイプが許可されていることをAppUpdateInfoオブジェクトが示しているかどうかを確認してください。
次のステップ
アプリ内アップデートをテストして、統合が正しく機能していることを 確認する。