Novedades de Web en Play

Fecha de publicación: 2 de diciembre de 2020

Desde que se introdujo la Actividad web de confianza, el equipo de Chrome facilita su uso con Bubblewrap. Agregamos funciones adicionales, como la integración de Facturación Google Play, y habilitamos que funcione en más plataformas, como ChromeOS.

Funciones de Bubblewrap y Trusted Web Activity

Bubblewrap te ayuda a crear apps que inicien tus AWP dentro de una actividad web confiable, sin necesidad de conocer las herramientas específicas de la plataforma.

Flujo de configuración simplificado

Anteriormente, usar Bubblewrap requería configurar manualmente el kit de desarrollo de Java y el SDK de Android, que son propensos a errores. La herramienta ahora ofrece descargar automáticamente las dependencias externas cuando se ejecuta por primera vez.

Si lo prefieres, puedes usar una instalación existente de las dependencias. El nuevo comando doctor ayuda a encontrar problemas y recomienda correcciones en la configuración, que ahora se puede actualizar desde la línea de comandos con el comando updateConfig.

Asistente mejorado

Cuando se crea un proyecto con init, Bubblewrap necesita información para generar la app para Android. La herramienta extrae valores del manifiesto de la app web y proporciona valores predeterminados cuando es posible.

Puedes cambiar esos valores cuando creas un proyecto nuevo, pero antes el significado de cada campo no era claro. Los diálogos de inicialización se volvieron a compilar con mejores descripciones y validación para cada campo de entrada.

Cómo mostrar compatibilidad con pantalla completa y orientación

En algunos casos, es recomendable que tu aplicación use la mayor parte posible de la pantalla y, cuando se compilan AWP, se implementa la configuración del campo display del manifiesto de la app web como fullscreen.

Cuando Bubblewrap detecta la opción de pantalla completa en el manifiesto de apps web, configura la aplicación para Android para que también se inicie en pantalla completa o en modo envolvente, en términos específicos de Android.

El campo orientation del manifiesto de la app web define si la aplicación se debe iniciar en modo vertical, horizontal o en la orientación que el dispositivo está usando actualmente. Bubblewrap ahora lee el campo del manifiesto de la app web y lo usa como predeterminado cuando creas la app para Android.

Puedes personalizar ambas configuraciones como parte del flujo bubblewrap init.

Salida de AppBundles

App Bundles es un formato de publicación para apps que delega la generación y la firma de APK finales a Play. En la práctica, esto permite que se entreguen archivos más pequeños a los usuarios cuando descargan la app desde la tienda.

Bubblewrap ahora empaqueta la aplicación como un paquete de aplicación, en un archivo llamado app-release-bundle.aab. Es preferible usar este formato cuando publiques apps en Play Store, ya que la tienda lo requiere a partir de 2021.

Delegación de la ubicación geográfica

Los usuarios esperan que las aplicaciones instaladas en sus dispositivos se comporten de manera coherente, independientemente de la tecnología. Cuando se usa dentro de Trusted Web Activity, el permiso de GeoLocation ahora se puede delegar al sistema operativo y, cuando se habilita, los usuarios ven los mismos diálogos que las apps compiladas con Kotlin o Java, y encuentran controles para administrar el permiso en el mismo lugar.

La función se puede agregar a través de Bubblewrap y, como agrega dependencias adicionales al proyecto de Android, solo debes habilitarla cuando la app web use el permiso de Geolocalización.

Objetos binarios optimizados

Los dispositivos con almacenamiento limitado son comunes en ciertas áreas del mundo, y los propietarios de esos dispositivos a menudo prefieren aplicaciones más pequeñas. Las aplicaciones que usan Trusted Web Activity producen objetos binarios pequeños, lo que quita parte de la ansiedad de esos usuarios.

Bubblewrap se optimizó reduciendo la lista de bibliotecas de Android necesarias, lo que genera objetos binarios que son 800 K más pequeños. En la práctica, eso es menos de la mitad del tamaño promedio que generaban las versiones anteriores. Para aprovechar los objetos binarios más pequeños, solo debes actualizar tu app con la versión más reciente de Bubblewrap.

Cómo actualizar una app existente

Una aplicación generada por Bubblewrap se compone de una aplicación web y un wrapper ligero de Android que abre la AWP. Si bien la AWP abierta dentro de una actividad web de confianza sigue los mismos ciclos de actualización que cualquier app web, el wrapper nativo puede y debe actualizarse.

Debes actualizar la app para asegurarte de que use la versión más reciente del wrapper, con las funciones y correcciones de errores más recientes. Con la versión más reciente de Bubblewrap instalada, el comando update aplica la versión más reciente del wrapper a un proyecto existente:

npm update -g @bubblewrap/cli
bubblewrap update
bubblewrap build

Otro motivo para actualizar esas aplicaciones es garantizar que los cambios en el manifiesto web se apliquen a la aplicación. Para ello, usa el nuevo comando merge:

bubblewrap merge
bubblewrap update
bubblewrap build

Actualizaciones de los criterios de calidad

En Chrome 86, se introdujeron cambios en los criterios de calidad de la actividad web de confianza, que se explican en detalle en Cambios en los criterios de calidad para las AWP que usan actividad web de confianza.

En resumen, debes asegurarte de que tus aplicaciones controlen las siguientes situaciones para evitar que fallen:

  • Error al verificar los vínculos de recursos digitales cuando se inicia la aplicación
  • No se muestra el estado HTTP 200 para una solicitud de recurso de red sin conexión.
  • Se muestra un error HTTP 404 o 5xx en la aplicación.

Además de garantizar que la aplicación pase la validación de Vínculos de recursos digitales, un service worker puede controlar las situaciones restantes:

self.addEventListener('fetch', event => {
  event.respondWith((async () => {
    try {
      return await fetchAndHandleError(event.request);
    } catch {
      // Failed to load from the network. User is offline or the response
      // has a status code that triggers the Quality Criteria.
      // Try loading from cache.
      const cachedResponse = await caches.match(event.request);
      if (cachedResponse) {
        return cachedResponse;
      }
      // Response was not found on the cache. Send the error / offline
      // page. OFFLINE_PAGE should be pre-cached when the service worker
      // is activated.
      return await caches.match(OFFLINE_PAGE);
    }
  })());
});

async function fetchAndHandleError(request) {
  const cache = await caches.open(RUNTIME_CACHE);
  const response = await fetch(request);

  // Throw an error if the response returns one of the status
  // that trigger the Quality Criteria.
  if (response.status === 404 ||
      response.status >= 500 && response.status < 600) {
    throw new Error(`Server responded with status: ${response.status}`);
  }

  // Cache the response if the request is successful.
  cache.put(request, response.clone());
  return response;
}

Workbox incorpora prácticas recomendadas y quita el texto de referencia cuando se usan trabajadores del servicio. Como alternativa, considera usar un complemento de Workbox para controlar esas situaciones:

export class FallbackOnErrorPlugin {
  constructor(offlineFallbackUrl, notFoundFallbackUrl, serverErrorFallbackUrl) {
    this.notFoundFallbackUrl = notFoundFallbackUrl;
    this.offlineFallbackUrl = offlineFallbackUrl;
    this.serverErrorFallbackUrl = serverErrorFallbackUrl;
  }

  checkTrustedWebActivityCrash(response) {
    if (response.status === 404 || response.status >= 500 && response.status <= 600) {
      const type = response.status === 404 ? 'E_NOT_FOUND' : 'E_SERVER_ERROR';
      const error = new Error(`Invalid response status (${response.status})`);
      error.type = type;
      throw error;
    }
  }

  // This is called whenever there's a network response,
  // but we want special behavior for 404 and 5**.
  fetchDidSucceed({response}) {
    // Cause a crash if this is a Trusted Web Activity crash.
    this.checkTrustedWebActivityCrash(response);

    // If it's a good response, it can be used as-is.
    return response;
  }

  // This callback is new in Workbox v6, and is triggered whenever
  // an error (including a NetworkError) is thrown when a handler runs.
  handlerDidError(details) {
    let fallbackURL;
    switch (details.error.details.error.type) {
      case 'E_NOT_FOUND': fallbackURL = this.notFoundFallbackUrl; break;
      case 'E_SERVER_ERROR': fallbackURL = this.serverErrorFallbackUrl; break;
      default: fallbackURL = this.offlineFallbackUrl;
    }

    return caches.match(fallbackURL, {
      // Use ignoreSearch as a shortcut to work with precached URLs
      // that have _WB_REVISION parameters.
      ignoreSearch: true,
    });
  }
}