Novità di Web in Play

Pubblicazione: 2 dicembre 2020

Dall'introduzione di Attività web attendibile, il team di Chrome ne ha semplificato l'utilizzo con Bubblewrap. Abbiamo aggiunto altre funzionalità, come l'integrazione della Fatturazione Google Play, e l'abbiamo resa compatibile con altre piattaforme, come ChromeOS.

Funzionalità di Bubblewrap e Attività web attendibile

Bubblewrap ti aiuta a creare app che avviano le tue PWA all'interno di un'Attività web attendibile, senza richiedere la conoscenza di strumenti specifici della piattaforma.

Flusso di configurazione semplificato

In precedenza, l'utilizzo di Bubblewrap richiedeva la configurazione manuale del Java Development Kit e dell'SDK Android, entrambi soggetti a errori. Ora lo strumento offre la possibilità di scaricare automaticamente le dipendenze esterne alla prima esecuzione.

Se preferisci, puoi comunque scegliere di utilizzare un'installazione esistente delle dipendenze. Il nuovo comando doctor aiuta a trovare i problemi e consiglia le correzioni alla configurazione, che ora possono essere aggiornate dalla riga di comando utilizzando il comando updateConfig.

Procedura guidata migliorata

Quando crei un progetto con init, Bubblewrap ha bisogno di informazioni per generare l'app per Android. Lo strumento estrae i valori dal file manifest dell'app web e fornisce i valori predefiniti, se possibile.

Puoi modificare questi valori quando crei un nuovo progetto, ma in precedenza il significato di ogni campo non era chiaro. Le finestre di dialogo di inizializzazione sono state ricostruite con descrizioni e convalide migliori per ogni campo di immissione.

Supporto della visualizzazione a schermo intero e dell'orientamento

In alcuni casi, potresti voler fare in modo che l'applicazione utilizzi la maggior parte dello schermo possibile e, quando crei PWA, questo viene implementato impostando il campo display dal manifest dell'app web su fullscreen.

Quando Bubblewrap rileva l'opzione fullscreen nel file manifest dell'app web, configura l'app per Android in modo che venga avviata anche a schermo intero o in modalità immersiva, in termini specifici di Android.

Il campo orientation del manifest dell'app web definisce se l'applicazione deve essere avviata in modalità Ritratto, Orizzontale o nell'orientamento attualmente utilizzato dal dispositivo. Bubblewrap ora legge il campo del manifest dell'app web e lo utilizza come valore predefinito durante la creazione dell'app per Android.

Puoi personalizzare entrambe le configurazioni nell'ambito del flusso bubblewrap init.

Output AppBundles

App Bundle è un formato di pubblicazione per le app che delega a Play la generazione e la firma finali dell'APK. In pratica, ciò consente di fornire file più piccoli agli utenti quando scaricano l'app dallo store.

Bubblewrap ora pacchettizza l'applicazione come app bundle, in un file denominato app-release-bundle.aab. Ti consigliamo di preferire questo formato quando pubblichi app sul Play Store, in quanto è richiesto dallo store dal 2021.

Delega della geolocalizzazione

Gli utenti si aspettano che le applicazioni installate sui loro dispositivi si comportino in modo coerente, indipendentemente dalla tecnologia. Se utilizzata all'interno di un'Attività web attendibile, l'autorizzazione GeoLocation ora può essere delegata al sistema operativo e, se attivata, gli utenti vedono le stesse finestre di dialogo delle app create con Kotlin o Java e trovano i controlli per gestire l'autorizzazione nello stesso posto.

La funzionalità può essere aggiunta tramite Bubblewrap e, poiché aggiunge ulteriori dipendenze al progetto Android, devi attivarla solo quando l'app web utilizza l'autorizzazione di geolocalizzazione.

File binari ottimizzati

I dispositivi con spazio di archiviazione limitato sono comuni in alcune aree del mondo e i proprietari di questi dispositivi spesso preferiscono applicazioni più piccole. Le applicazioni che utilizzano l'Attività web attendibile producono file binari di piccole dimensioni, il che elimina parte dell'ansia di questi utenti.

Bubblewrap è stato ottimizzato riducendo l'elenco delle librerie Android necessarie, il che ha portato a file binari generati più piccoli di 800 kB. In pratica, si tratta di meno della metà delle dimensioni medie generate dalle versioni precedenti. Per sfruttare i file binari più piccoli, devi solo aggiornare la tua app utilizzando l'ultima versione di Bubblewrap.

Come aggiornare un'app esistente

Un'applicazione generata da Bubblewrap è composta da un'applicazione web e da un wrapper Android leggero che apre la PWA. Anche se la PWA aperta all'interno di un'Attività web attendibile segue gli stessi cicli di aggiornamento di qualsiasi app web, il wrapper nativo può e deve essere aggiornato.

Devi aggiornare l'app per assicurarti che utilizzi l'ultima versione del wrapper, con le correzioni di bug e le funzionalità più recenti. Con l'ultima versione di Bubblewrap installata, il comando update applica l'ultima versione del wrapper a un progetto esistente:

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

Un altro motivo per aggiornare queste applicazioni è garantire che le modifiche al manifest web vengano applicate all'applicazione. Per farlo, utilizza il nuovo comando merge:

bubblewrap merge
bubblewrap update
bubblewrap build

Aggiornamenti ai criteri di qualità

Chrome 86 ha introdotto modifiche ai criteri di qualità delle Attività web attendibili, che sono spiegati in dettaglio in Modifiche ai criteri di qualità per le PWA che utilizzano l'Attività web attendibile.

In breve, devi assicurarti che le tue applicazioni gestiscano i seguenti scenari per evitare che si arrestino in modo anomalo:

  • Mancata verifica dei link agli asset digitali al lancio dell'applicazione
  • Mancata restituzione del codice HTTP 200 per una richiesta di risorsa di rete offline
  • Restituzione di un errore HTTP 404 o 5xx nell'applicazione.

Oltre a garantire che l'applicazione superi la convalida di Digital Asset Links, gli scenari rimanenti possono essere gestiti da un service worker:

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 le best practice e rimuove il boilerplate quando si utilizzano i service worker. In alternativa, puoi utilizzare un plug-in Workbox per gestire questi scenari:

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