Compatibilidad con actualizaciones dentro de la app (Unity)

En esta guía, se describe cómo admitir las actualizaciones dentro de la app en tu app con Unity. Hay guías diferentes para casos en los que tu implementación usa el lenguaje de programación Kotlin o el lenguaje de programación Java, y casos en los que tu implementación usa código nativo (C/C++).

Cómo configurar tu entorno de desarrollo

OpenUPM-CLI

Si tienes instalada la CLI de OpenUPM, puedes instalar el registro de OpenUPM con el siguiente comando:

openupm add com.google.play.appupdate

OpenUPM

  1. Para abrir la configuración del administrador de paquetes, selecciona la opción de menú de Unity Edit > Project Settings > Package Manager.

  2. Agrega OpenUPM como un registro con alcance a la ventana del Administrador de paquetes:

    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.appupdate
    
  3. Para abrir el menú del administrador de paquetes, selecciona la opción de menú de Unity Window > Package Manager.

  4. Establece el menú desplegable de alcance del administrador para seleccionar Mis registros.

  5. Selecciona el paquete Google Play Integrity plugin for Unity de la lista de paquetes y presiona Install.

Importa desde GitHub

  1. Descarga la versión más reciente de .unitypackage desde GitHub.

  2. Importa el archivo .unitypackage. Para ello, selecciona la opción del menú de Unity Assets > Import package > Custom Package e importa todos los elementos.

Descripción general del SDK de Unity

La API de actualización integrada en la app de Play forma parte de la familia del SDK de Play Core. El complemento de Unity ofrece una clase AppUpdateManager para controlar la comunicación entre tu app y la API de Play. Debes crear una instancia de esta clase a fin de poder usarla para administrar actualizaciones en la app:

AppUpdateManager appUpdateManager = new AppUpdateManager();

Cómo comprobar la disponibilidad de actualizaciones

Antes de solicitar una actualización, comprueba si hay una actualización disponible para tu app. Usa AppUpdateManager para buscar actualizaciones en una corrutina:

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.
  }
}

La instancia AppUpdateInfo que se muestra contiene el estado de disponibilidad de la actualización. Si una actualización integrada en la app ya está en curso, la instancia también informa el estado de esa actualización.

Cómo verificar la obsolescencia de las actualizaciones

Además de comprobar si hay actualizaciones disponibles, te recomendamos que verifiques cuánto tiempo pasó desde que el usuario recibió una notificación sobre una actualización a través de Google Play Store. Esto puede ayudarte a decidir si debes iniciar una actualización flexible o una actualización inmediata. Por ejemplo, podrías esperar unos días antes de notificar al usuario con una actualización flexible y, luego, solicitar una actualización inmediata.

Usa ClientVersionStalenessDays para verificar cuántos días pasaron desde que apareció la actualización en Play Store:

var stalenessDays = appUpdateInfoOperation.ClientVersionStalenessDays;

Cómo verificar la prioridad de las actualizaciones

La API de Google Play Developer te permite establecer la prioridad de cada actualización. De esta manera, tu app puede determinar la insistencia con la que recomendará una actualización al usuario. Por ejemplo, considera la siguiente estrategia para establecer la prioridad de las actualizaciones:

  • Mejoras menores en la IU: Actualización de baja prioridad. No solicites una actualización flexible ni una actualización inmediata.
  • Mejoras en el rendimiento: actualización de prioridad media. Solicita una actualización flexible.
  • Actualización crítica de seguridad: actualización de prioridad alta. Requiere una actualización inmediata.

Para determinar la prioridad, Google Play usa un valor entero entre 0 y 5, en el que 0 es la prioridad predeterminada y 5 es la más alta. A fin de establecer la prioridad para una actualización, usa el campo inAppUpdatePriority en Edits.tracks.releases en la API de Google Play Developer. Se considerará que todas las versiones agregadas en la original tendrán establecida la misma prioridad que esta última. Solo se puede establecer la prioridad al momento de lanzar una versión nueva; no se puede cambiar más tarde.

Establece la prioridad mediante la API de Google Play Developer como se describe en la documentación de la API de Play Developer. La prioridad de la actualización integrada en la app debe especificarse en el recurso Edit.tracks que se pasa en el método Edit.tracks: update. En el siguiente ejemplo, se muestra cómo lanzar una app con código de versión 88 y inAppUpdatePriority 5:

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

En el código de tu app, puedes verificar el nivel de prioridad de una actualización determinada con UpdatePriority:

var priority = appUpdateInfoOperation.UpdatePriority;

Cómo iniciar una actualización

Después de asegurarte de que haya una actualización disponible, puedes solicitar una actualización con AppUpdateManager.StartUpdate(). Antes de solicitar una actualización, asegúrate de tener un objeto AppUpdateInfo actualizado. También debes crear un objeto AppUpdateOptions para configurar el flujo de actualización.

En el siguiente ejemplo, se crea un objeto AppUpdateOptions para un flujo de actualización inmediato:

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

En el siguiente ejemplo, se crea un objeto AppUpdateOptions para un flujo de actualización flexible:

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

El objeto AppUpdateOptions también contiene un campo AllowAssetPackDeletion que define si la actualización puede borrar paquetes de recursos si el almacenamiento del dispositivo es limitado. Este campo se establece en false de forma predeterminada, pero puedes pasar el argumento opcional allowAssetPackDeletion a ImmediateAppUpdateOptions() o FlexibleAppUpdateOptions() para configurarlo en true en su lugar:

// 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);

Los pasos siguientes dependerán de si solicitas una actualización flexible o una actualización inmediata.

Cómo manejar una actualización flexible

Una vez que tengas un objeto AppUpdateInfo actualizado y un objeto AppUpdateOptions configurado correctamente, puedes llamar a AppUpdateManager.StartUpdate() para solicitar de forma asíncrona un flujo de actualización.

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;
  }

}

Para un flujo de actualización flexible, debes activar la instalación de la actualización de la app una vez que la descarga finalice correctamente. Para ello, llama a AppUpdateManager.CompleteUpdate(), como se muestra en el siguiente ejemplo:

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).
}

Cómo manejar una actualización inmediata

Una vez que tengas un objeto AppUpdateInfo actualizado y un objeto AppUpdateOptions configurado correctamente, puedes llamar a AppUpdateManager.StartUpdate() para solicitar de forma asíncrona un flujo de actualización.

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).
}

Para obtener un flujo de actualización inmediata, Google Play muestra un cuadro de diálogo de confirmación del usuario. Cuando el usuario acepta la solicitud, Google Play descarga e instala automáticamente la actualización, luego, reinicia la app a la versión actualizada si la instalación se realizó correctamente.

Administración de errores

En esta sección, se describen las soluciones de errores comunes.

  • Si StartUpdate() lanza un elemento ArgumentNullException, significa que el valor de AppUpdateInfo es nulo. Asegúrate de que el objeto AppUpdateInfo que muestra GetAppUpdateInfo() no sea nulo antes de iniciar el flujo de actualización.
  • Si PlayAsyncOperation muestra el código de error ErrorUpdateUnavailable, asegúrate de que haya una versión actualizada de la app que tenga el mismo ID de aplicación y la misma clave de firma.
  • Si PlayAsyncOperation muestra el código de error ErrorUpdateNotAllowed, significa que el objeto AppUpdateOptions indica un tipo de actualización que no se permite para la actualización disponible. Comprueba que el objeto AppUpdateInfo indique que el tipo de actualización seleccionado está permitido antes de iniciar el flujo correspondiente.

Próximos pasos

Prueba las actualizaciones en la app para verificar que la integración funcione correctamente.