Novità di Web in Play

Data di pubblicazione: 2 dicembre 2020

Da quando è stata introdotta l'attività web attendibile, il team di Chrome ne ha semplificato l'utilizzo con Bubblewrap. Abbiamo aggiunto funzionalità aggiuntive, come la integrazione della fatturazione di Google Play, e abbiamo consentito il funzionamento su più 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 quando viene eseguito per la prima volta.

Se preferisci, puoi comunque scegliere di utilizzare un'installazione esistente delle dipendenze. Il nuovo comando doctor consente di trovare i problemi e consiglia le correzioni alla configurazione, che ora può essere aggiornata 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 ciascun campo non era chiaro. Le finestre di dialogo di inizializzazione sono state ricostruite con descrizioni e convalida migliori per ogni campo di immissione.

Supporto per lo schermo intero e l'orientamento del display

In alcuni casi, potresti volere che la tua applicazione utilizzi la maggior parte dello schermo possibile e, quando sviluppi PWA, questo viene implementato impostando il campo display del file manifest dell'app web su fullscreen.

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

Il campo orientation del file manifest dell'app web definisce se l'applicazione deve essere avviata in modalità Ritratto, Orizzontale o nell'orientamento attualmente in uso sul dispositivo. Il fumetto ora legge il campo Manifest dell'app web e lo utilizza come impostazione predefinita durante la creazione dell'app per Android.

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

Output di AppBundles

App Bundle è un formato di pubblicazione per le app che delegano a Google Play la generazione e la firma dell'APK finale. In pratica, ciò consente di mostrare agli utenti file di dimensioni minori durante il download dell'app dallo store.

Ora Bubblewrap pacchettizza l'applicazione come App Bundle in un file chiamato app-release-bundle.aab. Ti consigliamo di preferire questo formato quando pubblichi app sul Play Store, in quanto obbligatorio per lo store a partire dal 2021.

Delega di 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, ora l'autorizzazione GeoLocation può essere delegata al sistema operativo e, se attivata, gli utenti visualizzano 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 dipendenze aggiuntive al progetto Android, devi attivarla solo quando l'app web utilizza l'autorizzazione di geolocalizzazione.

Programmi binari ottimizzati

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

Bubblewrap è stato ottimizzato riducendo l'elenco delle librerie Android necessarie, con un risultato finale costituito da file binari generati di 800 KB più piccoli. In pratica, è meno della metà delle dimensioni medie generate dalle versioni precedenti. Per sfruttare i binari più piccoli, devi solo aggiornare la tua app utilizzando la versione più recente 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.

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

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

Un altro motivo per aggiornare queste applicazioni è assicurarsi che le modifiche al manifest web vengano applicate all'applicazione. A tale scopo, 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à dell'Attività web attendibile, che sono illustrati in dettaglio nella sezione Modifiche ai criteri di qualità per le PWA che utilizzano l'Attività web attendibile.

Per riassumere brevemente, devi assicurarti che le tue applicazioni gestiscano i seguenti scenari per impedire l'arresto anomalo:

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

Oltre ad assicurarti 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 applica le best practice e rimuove il codice boilerplate quando utilizzi i worker di servizio. In alternativa, valuta l'utilizzo di 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,
    });
  }
}