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, carecía de integración con el sistema operativo. Hasta hace poco, ni siquiera se podían instalar. Afortunadamente, esto cambió. Ahora podemos aprovechar esa integración para agregar funciones útiles a nuestras AWP. Exploremos algunas de esas opciones.

Cómo trabajar con el sistema de archivos

Un flujo de trabajo típico del usuario que usa archivos se ve de la siguiente manera:

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

Antes de la API de Acceso al sistema de archivos, las apps web no podían realizar esta acción. Para abrir los archivos, se requería una carga de archivos, y para guardar los cambios, los usuarios debían descargarlos. Además, la Web no tenía acceso 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. A continuación, se detalla el resto de la configuración para abrir un archivo:

  1. Captura el controlador de archivo de la API del selector de archivos del acceso al sistema de archivos. Allí encontrará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 cambios en un archivo, también necesitas un gesto del usuario; luego:

  1. Usa el controlador de archivo para crear una FileSystemWritableFileStream.
  2. Realiza los cambios necesarios en el flujo. Esto no actualizará el archivo. En su lugar, se suele crear un archivo temporal.
  3. Por último, cuando hayas terminado de realizar los cambios, cierras la transmisión, lo que hace que los cambios pasen de temporales a permanentes.

Veamos esto 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 aplicación, pero ¿qué pasa al revés? Los usuarios quieren establecer su app favorita como predeterminada para abrir archivos. La API de control de archivos es una API experimental que permite a las AWP instaladas: Registrarse como un controlador de archivos en el dispositivo de un usuario y especificar el tipo de MIME y la extensión de archivo que admite la AWP en el manifiesto de la aplicación 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. Este es un ejemplo de la configuración del manifiesto para que una AWP lea archivos de texto:

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

Control de URLs

Con el manejo de URLs, tu AWP puede capturar vínculos que forman parte de su alcance desde el sistema operativo y renderizarlos dentro de una ventana de la AWP, en lugar de la pestaña del navegador predeterminado. Por ejemplo, si recibe un mensaje con un vínculo a la AWP o hace 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 WebAPK, como cuando los usuarios instalan una AWP con Chrome. Es imposible capturar URLs de AWP instaladas en iOS y iPadOS desde Safari.

Para los navegadores de escritorio, la comunidad de navegadores web creó una especificación nueva. Por el momento, esta especificación es experimental y agrega un nuevo miembro del archivo de manifiesto: url_handlers. Esta propiedad espera un array de orígenes que la AWP desea capturar. El origen de tu AWP se otorgará automáticamente, y cada origen debe aceptar ese control operando 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 quieres agregar el origen app.web.dev, debería verse de la siguiente manera:

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

En este caso, el navegador verificará si existe un archivo en app.web.dev/.well-known/web-app-origin-association y aceptará el control de la URL desde la URL del permiso de la AWP. El desarrollador debe crear este archivo. En el siguiente ejemplo, el archivo se ve así:

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

Control de protocolos de URL

El control de URL funciona con URLs de protocolo https estándar, pero es posible usar esquemas de URI personalizados, como pwa://. En varios sistemas operativos, las apps instaladas adquieren esta capacidad mediante el registro de 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 registrarte, puedes usar el métodoregisterProtocolHandler() o el miembro protocol_handlers en tu manifiesto, con el esquema deseado y la URL que quieras cargar en el contexto de tu 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 de escape que activó la operación. Por lo tanto, 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 los dispositivos de los usuarios en cada plataforma. Solo debes crear un vínculo o usar navigator.href, apuntar al esquema de URI que desees y pasar los argumentos en forma de escape de URL.

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

Compartir en la Web

Navegadores compatibles

  • 89
  • 93
  • 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 comprobar si el dispositivo actual puede compartir datos simples, como texto, comprueba la presencia del método navigator.share() para compartir archivos. Luego, comprueba la presencia del método navigator.canShare().

Para solicitar la acción de compartir, llama 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 abre la hoja compartida gracias a Compartir en la Web.

Objetivo de uso compartido de la Web

La API de Web Share Target permite que tu AWP sea el objetivo de una operación de uso compartido de otra app en ese dispositivo, ya 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 la AWP. El navegador registra el objetivo de uso compartido en el sistema operativo cuando se instala la app.

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

action
URL que se cargará en una ventana de la AWP que se espera que reciba los datos compartidos
method
Se usará el método de verbo HTTP para la acción, como GET, POST o PUT.
enctype
(Opcional) El tipo de codificación de los parámetros es application/x-www-form-urlencoded de forma predeterminada, pero también se puede establecer como multipart/form-data para métodos como POST.
params
Es un objeto que asignará datos compartidos (de las claves title, text, url y files de Web Share) a 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, si deseas definir para tu AWP que deseas recibir datos compartidos (solo el título y la URL), agrega en el manifiesto lo siguiente:

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

En el ejemplo anterior, si alguna app del sistema comparte una URL con un título y el usuario elige tu AWP en el diálogo, el navegador creará una nueva navegación a /receive-share/?shared_title=AAA&shared_url=BBB de origen, donde 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 utilizará el nombre y el ícono de la AWP de tu manifiesto para proporcionar la entrada de uso compartido del sistema operativo. No puedes elegir un conjunto diferente para ese propósito.

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

Seleccionador de contactos

Navegadores compatibles

  • x
  • x
  • x
  • x

Origen

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

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

Puedes solicitar que las propiedades disponibles se consulten con navigator.contacts.getProperties() y solicitar una selección de contactos individuales o múltiples con una lista de las propiedades deseadas.

Algunas propiedades de ejemplo son name, email, address y tel. Cuando le pides al usuario que elija uno o más contactos, puedes llamar a navigator.contacts.select(properties) y pasarle un array de propiedades que desees obtener.

En el siguiente ejemplo, se enumeran los contactos que recibió 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