Integración en el SO

Las apps web tienen un gran alcance. Se ejecutan en varias plataformas. Son fáciles de compartir a través de vínculos. Pero tradicionalmente no tenían integración con el sistema operativo. Hasta hace poco, ni siquiera podían instalarse. Afortunadamente, eso cambió y ahora podemos aprovechar esa integración para agregar funciones útiles a nuestras AWP. Exploremos algunas de esas opciones.

Un flujo de trabajo típico de los usuarios con archivos se ve de la siguiente manera:

  • Elige un archivo o una carpeta del dispositivo y ábrelo directamente.
  • Realiza los cambios en esos archivos o carpetas y vuelve a guardarlos directamente.
  • Crear nuevos archivos y carpetas

Antes de la API de File System Access, las aplicaciones web no podían hacer esto. La apertura de archivos requería subir el archivo, guardar los cambios requería que los usuarios los descargaran y la Web no tenía acceso en absoluto para crear nuevos archivos y carpetas en el sistema de archivos del usuario.

Abrir un archivo

Para abrir un archivo, usamos el método window.showOpenFilePicker(). Ten en cuenta que este método requiere un gesto del usuario, como un clic en un botón. Este es el resto de la configuración para abrir un archivo:

  1. Captura el controlador de archivos de la API del selector de archivos del acceso al sistema de archivos. Recibirás información básica sobre el archivo.
  2. Con el método getFile() del controlador, obtendrás un tipo especial de Blob llamado File que incluye propiedades adicionales de solo lectura (como el nombre y la fecha de la última modificación) sobre el archivo. Como es un BLOB, se puede llamar a sus métodos, como text(), para obtener su contenido.
// Have the user select a file.
const [ handle ] = await window.showOpenFilePicker();
// Get the File object from the handle.
const file = await handle.getFile();
// Get the file content.
// Also available, slice(), stream(), arrayBuffer()
const content = await file.text();

Guardando los cambios

Para guardar los cambios en un archivo, también necesitas un gesto del usuario. luego:

  1. Usa el controlador de archivos para crear un FileSystemWritableFileStream.
  2. Realiza los cambios necesarios en la transmisión. Esto no actualizará el archivo. sino que se suele crear un archivo temporal.
  3. Por último, cuando terminas de realizar los cambios, cierras la transmisión. Esto hace que los cambios pasen de ser temporales a permanentes.

Veámoslo en el código:

// Make a writable stream from the handle.
const writable = await handle.createWritable();
// Write the contents of the file to the stream.
await writable.write(contents);
// Close the file and write the contents to disk.
await writable.close();

Manejo de archivos

La API de File System Access te permite abrir archivos desde tu app, pero ¿y viceversa? Los usuarios quieren establecer su app favorita como la opción predeterminada para abrir archivos. La API de manejo de archivos es una API experimental que permite a las AWP instaladas hacer lo siguiente: Regístrate como controlador de archivos en el dispositivo de un usuario y especifica el tipo de MIME y la extensión de archivo que admite la AWP en el manifiesto de la app web. Puedes especificar íconos de archivo personalizados para las extensiones compatibles.

Una vez que se registre, la AWP instalada aparecerá como una opción del sistema de archivos del usuario, lo que le permitirá abrir el archivo directamente en ella. A continuación, se muestra un ejemplo de la configuración del manifiesto para que una AWP lea archivos de texto:

...
"file_handlers": [
     {
         "action": "/open-file",
         "accept": {
             "text/*": [".txt"]
         }
     }
]
...

Manejo de URLs

Con el manejo de URLs, tu AWP puede capturar vínculos del sistema operativo que forman parte de su alcance y renderizarlos en una ventana de la AWP, en lugar de en la pestaña predeterminada del navegador. Por ejemplo, si recibes un mensaje que vincula a la AWP o haces clic en un vínculo directo (una URL que dirige a un contenido específico) en la AWP, el contenido se abrirá en una ventana independiente.

Este comportamiento está disponible automáticamente en Android cuando se usa el WebAPK, como cuando los usuarios instalan una AWP con Chrome. Es imposible capturar URLs desde Safari en AWP instaladas en iOS y iPadOS.

Para los navegadores de escritorio, la comunidad de navegadores web creó una especificación nueva. Esta especificación es actualmente experimental. se agrega un nuevo miembro del archivo de manifiesto: url_handlers. Esta propiedad espera un array de orígenes que la AWP quiere capturar. El origen de tu AWP se otorgará automáticamente, y los demás orígenes deben aceptar que la administración se realice a través de un archivo llamado web-app-origin-association. Por ejemplo, si el manifiesto de tu AWP está alojado en web.dev y deseas agregar el origen app.web.dev, se verá de la siguiente manera:

"url_handlers": [
    {"origin": "https://app.web.dev"},
]

En este caso, el navegador comprobará si existe un archivo en app.web.dev/.well-known/web-app-origin-association y acepta el manejo de URLs desde la URL de alcance de la AWP. El desarrollador debe crear este archivo. En el siguiente ejemplo, el archivo se ve de la siguiente manera:

{
    "web_apps": [
        {
            "manifest": "/mypwa/app.webmanifest",
            "details": {
                "paths": [ "/*" ]
            }
        }
    ]
}

Manejo de protocolos de URL

El control de URL funciona con las URLs de protocolo https estándar, pero es posible usar esquemas de URI personalizados, como pwa://. En varios sistemas operativos, las apps instaladas obtienen esta capacidad cuando las apps registran sus esquemas.

Para la AWP, esta función se habilita con la API del controlador de protocolo de URL, disponible solo en dispositivos de escritorio. Solo puedes permitir protocolos personalizados para dispositivos móviles si distribuyes tu AWP en tiendas de aplicaciones.

Para realizar el registro, puedes usar el métodoregisterProtocolHandler() o el miembro protocol_handlers en su manifiesto con el esquema deseado y la URL que desea cargar en el contexto de su AWP, por ejemplo:

...
{
  "protocol_handlers": [
    {
      "protocol": "web+pwa",
      "url": "/from-protocol?value=%s"
    },
  ]
}
...

Puedes enrutar la URL from-protocol al controlador correcto y obtener la cadena de consulta value en tu AWP. %s es un marcador de posición para la URL con escape que activó la operación, por lo que si tienes un vínculo en algún lugar como <a href="web+pwa://testing">, tu AWP abrirá /from-protocol?value=testing.

Llamar a otras apps

Puedes usar esquemas de URI para conectarte a cualquier otra app instalada (AWP o no) en las aplicaciones en todas las plataformas. Solo debes crear un vínculo o usar navigator.href, señalar el esquema de URI que desees y pasar los argumentos en formato de escape de URL.

Puedes usar esquemas estándar conocidos, como tel: para llamadas telefónicas, mailto: para el envío de correos electrónicos o sms: para mensajes de texto. o puedes obtener información sobre las funciones Esquemas de URL, por ejemplo, de mensajes, mapas, navegación, reuniones en línea, redes sociales y tiendas de aplicaciones conocidos

Compartir en la Web

Navegadores compatibles

  • Chrome: 89.
  • Borde: 93.
  • Firefox: detrás de una marca.
  • Safari: 12.1.

Origen

Con la API de Web Share, tu AWP puede enviar contenido a otras apps instaladas en el dispositivo a través del canal compartido.

La API solo está disponible en sistemas operativos con un mecanismo share, incluidos Android, iOS, iPadOS, Windows y ChromeOS. Puedes compartir un objeto que contenga lo siguiente:

  • Texto (propiedades title y text)
  • Una URL (propiedad url)
  • Archivos (propiedad files).

Para verificar si el dispositivo actual puede compartir datos simples, como texto, verifica la presencia del método navigator.share() y comparte los archivos que compruebas con el método navigator.canShare().

Puedes solicitar la acción de uso compartido llamando a navigator.share(objectToShare). Esa llamada muestra una promesa que se resuelve con undefined o se rechaza con una excepción.

Chrome en Android y Safari en iOS abriendo la hoja compartida gracias a Web Share.

Objetivo de uso compartido en la Web

La API de Web Share Target permite que tu AWP sea un objetivo de una operación de uso compartido de otra app en ese dispositivo, independientemente de que sea una AWP o no. Tu AWP recibe los datos que comparte otra app.

Actualmente, está disponible en Android con WebAPK y ChromeOS, y solo funciona después de que el usuario instala tu AWP. El navegador registra el objetivo de uso compartido en el sistema operativo cuando se instala la app.

Configura el objetivo de uso compartido web en el manifiesto con el miembro share_target definido en la especificación de borrador del objetivo de Web Share. share_target se establece en un objeto con algunas propiedades:

action
URL que se cargará en una ventana de AWP que se espera que reciba los datos compartidos.
method
Se usará el método verbo HTTP para la acción, como GET, POST o PUT.
enctype
El tipo de codificación de los parámetros(opcional). De forma predeterminada, es application/x-www-form-urlencoded, pero también se puede establecer como multipart/form-data para métodos como POST.
params
Un objeto que asignará datos de uso compartido (de las claves title, text, url y files de Web Share) a los argumentos que el navegador pasará en la URL (en method: 'GET') o en el cuerpo de la solicitud con la codificación seleccionada.

Por ejemplo, puedes agregar lo siguiente a tu manifiesto para definir que quieres recibir datos compartidos (solo título y URL) para tu AWP:

...
"share_target": {
   "action": "/receive-share/",
   "method": "GET",
   "params": {
      "title": "shared_title",
      "url": "shared_url"
   }
}
...

En el ejemplo anterior, si una app del sistema comparte una URL con un título y el usuario selecciona tu AWP en el diálogo, el navegador creará una nueva navegación al /receive-share/?shared_title=AAA&shared_url=BBB de tu origen, en el que AAA es el título compartido y BBB es la URL compartida. Puedes usar JavaScript para leer esos datos de la cadena window.location analizándolos con el constructor URL.

El navegador usará el nombre y el ícono de la AWP de tu manifiesto para alimentar la entrada de uso compartido del sistema operativo. No puedes elegir un conjunto diferente para ese propósito.

Para ver ejemplos más detallados y ver cómo recibir archivos, consulta Cómo recibir datos compartidos con la API de Web Share Target

Seleccionador de contactos

Navegadores compatibles

  • Chrome no es compatible.
  • Edge: no es compatible.
  • Firefox: No es compatible.
  • Safari: no es compatible.

Origen

Con la API de Contact Picker, puedes solicitar que el dispositivo renderice un diálogo nativo con todos los contactos del usuario para que este pueda elegir uno o más. Tu AWP podrá recibir los datos que desees de esos contactos.

La API del selector de contactos está disponible principalmente en dispositivos móviles, y todo se hace a través de la interfaz navigator.contacts en plataformas compatibles.

Puedes solicitar las propiedades disponibles para realizar consultas con navigator.contacts.getProperties() y solicitar una selección de uno o varios contactos con una lista de propiedades deseadas.

Algunas propiedades de ejemplo son name, email, address y tel. Cuando le pidas al usuario que elija uno o más contactos, podrás llamar a navigator.contacts.select(properties) y pasar una serie de propiedades que quieras obtener a cambio.

En el siguiente ejemplo, se enumeran los contactos que recibe el selector.

async function getContacts() {
   const properties = ['name', 'email', 'tel'];
   const options = { multiple: true };
   try {
     const contacts = await navigator.contacts.select(properties, options);
     console.log(contacts);
   } catch (ex) {
     // Handle any errors here.
   }
}

Recursos