このガイドでは、Unity を使用してアプリ内でアプリ内アップデートをサポートする方法について説明します。実装に Kotlin プログラミング言語または Java プログラミング言語を使用するケースと、ネイティブ コード(C / C++)を使用するケースについては、個別のガイドが用意されています。
開発環境をセットアップする
Play In-App Update Unity Plugin の最新リリースを 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
を使用して、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: 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 でないことを確認してください。PlayAsyncOperation
からErrorUpdateUnavailable
エラーコードが返された場合は、同じアプリケーション ID と署名鍵を持つアプリの更新バージョンが存在することを確認してください。PlayAsyncOperation
がErrorUpdateNotAllowed
エラーコードを返す場合は、AppUpdateOptions
オブジェクトが入手可能なアップデートで許可されていないアップデート タイプを示していることを表しています。アップデート フローを開始する前に、選択したアップデート タイプが許可されていることをAppUpdateInfo
オブジェクトが示しているかどうかを確認してください。
次のステップ
アプリ内アップデートをテストして、統合が正しく機能していることを確認する。