Integração com o SO

Os apps da Web têm um grande alcance. Eles são executados em várias plataformas. Eles são fáceis de compartilhar por links. Mas, tradicionalmente, eles não tinham integração com o sistema operacional. Até pouco tempo atrás, eles nem sequer eram instaláveis. Felizmente, isso mudou e agora podemos aproveitar essa integração para adicionar recursos úteis aos nossos PWAs. Vamos conhecer algumas dessas opções.

Um fluxo de trabalho típico do usuário que usa arquivos tem a seguinte aparência:

  • Escolha um arquivo ou pasta do dispositivo e abra o item diretamente.
  • Faça alterações nesses arquivos ou pastas e salve as alterações diretamente.
  • Crie novos arquivos e pastas.

Antes da API File System Access, os apps da Web não podiam fazer isso. Abrir os arquivos exigia um upload de arquivos, salvar as alterações exigia que os usuários baixem-os, e a Web não tinha nenhum acesso para criar novos arquivos e pastas no sistema de arquivos do usuário.

Abrir um arquivo

Para abrir um arquivo, usamos o método window.showOpenFilePicker(). Esse método exige um gesto do usuário, como o clique de um botão. Veja o restante da configuração para abrir um arquivo:

  1. Capture o identificador do arquivo da API do seletor de arquivos de acesso ao sistema de arquivos. Isso fornece informações básicas sobre o arquivo.
  2. Usando o método getFile() do gerenciador, você vai receber um tipo especial de Blob chamado File, que inclui outras propriedades somente leitura (como nome e data da última modificação) sobre o arquivo. Por ser um Blob, os métodos dele podem ser chamados, como text(), para receber o conteúdo.
// 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();

Salvando alterações

Para salvar alterações em um arquivo, você também precisa de um gesto do usuário. então:

  1. Use o identificador de arquivo para criar um FileSystemWritableFileStream.
  2. Faça alterações no fluxo. Isso não atualizará o arquivo. Em vez disso, um arquivo temporário é criado normalmente.
  3. Por fim, quando terminar de fazer as alterações, você fecha o stream, o que move as alterações de temporárias para permanentes.

Vamos conferir isso no 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();

Processamento de arquivos

A API File System Access permite abrir arquivos de dentro do seu aplicativo, mas e o contrário? Os usuários querem definir o app favorito deles como padrão para abrir arquivos. A API File Handling (em inglês) é uma API experimental que permite PWAs instalados: Registre-se como um gerenciador de arquivos no dispositivo de um usuário, especificando o tipo MIME e a extensão de arquivo compatíveis com o PWA no manifesto do app da Web. Você pode especificar ícones de arquivos personalizados para as extensões suportadas.

Depois de registrado, o PWA instalado vai aparecer como uma opção no sistema de arquivos do usuário, permitindo que ele abra o arquivo diretamente. Confira um exemplo de configuração de manifesto para um PWA ler arquivos de texto:

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

Processamento de URL

Com o processamento de URLs, o PWA captura links que fazem parte do escopo do sistema operacional e os renderiza em uma janela do PWA, em vez de na guia do navegador padrão. Por exemplo, se você receber uma mensagem com um link para o PWA ou clicar em um link direto (um URL que aponta para um conteúdo específico) no PWA, o conteúdo será aberto em uma janela independente.

Esse comportamento fica disponível automaticamente no Android quando o WebAPK é usado, como quando os usuários instalam um PWA com o Chrome. É impossível capturar URLs em PWAs instalados no iOS e iPadOS pelo Safari.

Para navegadores desktop, a comunidade de navegadores da Web criou uma nova especificação. No momento, essa especificação é experimental. ele vai adicionar um novo membro ao arquivo de manifesto: url_handlers. Essa propriedade espera uma matriz de origens que o PWA quer capturar. A origem do seu PWA será concedida automaticamente, e as outras origens precisam aceitar esse processamento operando por meio de um arquivo chamado web-app-origin-association. Por exemplo, se o manifesto do PWA estiver hospedado em web.dev e você quiser adicionar a origem do app.web.dev, ele vai ficar assim:

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

Nesse caso, o navegador vai verificar se há um arquivo em app.web.dev/.well-known/web-app-origin-association, aceitando o processamento do URL do escopo do PWA. O desenvolvedor precisa criar esse arquivo. No exemplo abaixo, o arquivo é assim:

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

Processamento do protocolo de URL

O processamento de URLs funciona com URLs de protocolo https padrão, mas é possível usar esquemas de URI personalizados, como pwa://. Em vários sistemas operacionais, os aplicativos instalados recebem essa capacidade por meio do registro de esquemas.

No caso dos PWAs, esse recurso é ativado usando a API do gerenciador de protocolo de URL, disponível apenas em dispositivos desktop. Distribua seu PWA nas app stores para permitir protocolos personalizados para dispositivos móveis.

Para fazer o registro, use o métodoregister ProtocolHandler() ou o membro protocol_handlers no manifesto, com o esquema e o URL que você quer carregar no contexto do PWA, por exemplo:

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

É possível rotear o URL from-protocol para o gerenciador correto e receber a string de consulta value no PWA. O %s é um marcador para o URL com escape que acionou a operação. Portanto, se você tiver um link em algum lugar, como <a href="web+pwa://testing">, o PWA abrirá /from-protocol?value=testing.

Ligar para outros apps

Você pode usar esquemas de URI para se conectar a qualquer outro app instalado (PWA ou não) nos usuários dispositivos em todas as plataformas. Você só precisa criar um link ou usar navigator.href e apontar para o esquema de URI desejado, transmitindo os argumentos no formato escapado do URL.

É possível usar esquemas padrão conhecidos, como tel: para chamadas telefônicas, mailto: para envio de e-mails ou sms: para mensagens de texto. ou sobre outros apps Esquemas de URL, por exemplo, de mensagens conhecidas, mapas, navegação, reuniões on-line, redes sociais e app stores.

Compartilhamento na Web

Compatibilidade com navegadores

  • Chrome: 89.
  • Borda: 93.
  • Firefox: atrás de uma sinalização.
  • Safari: 12.1.

Origem

Com a API Web Share, seu PWA pode enviar conteúdo para outros apps instalados no dispositivo pelo canal compartilhado.

A API só está disponível em sistemas operacionais com um mecanismo share, incluindo Android, iOS, iPadOS, Windows e ChromeOS. Você pode compartilhar um objeto que contenha:

  • Texto (propriedades title e text)
  • Um URL (propriedade url)
  • Arquivos (propriedade files).

Para conferir se o dispositivo atual pode compartilhar, para dados simples, como texto, verifique a presença do método navigator.share() para compartilhar os arquivos que você verifica se o método navigator.canShare() está presente.

Para solicitar a ação de compartilhamento, chame navigator.share(objectToShare). Essa chamada retorna uma promessa que é resolvida com undefined ou é rejeitada com uma exceção.

Chrome no Android e Safari no iOS abrindo a planilha de compartilhamento com o compartilhamento na Web.

Destino de compartilhamento da Web

A API Web Share Target permite que seu PWA seja o destino de uma operação de compartilhamento de outro app no dispositivo, seja ele um PWA ou não. O PWA recebe os dados compartilhados por outro app.

No momento, ele está disponível no Android com o WebAPK e o ChromeOS e só funciona depois que o usuário instala o PWA. O navegador registra o alvo de compartilhamento no sistema operacional quando o app é instalado.

Você configura o alvo de compartilhamento da Web no manifesto com o membro share_target definido na especificação de rascunho do alvo do compartilhamento da Web. share_target é definido como um objeto com algumas propriedades:

action
O URL que será carregado em uma janela do PWA que deve receber os dados compartilhados.
method
O método verbo HTTP vai ser usado para a ação, como GET, POST ou PUT.
enctype
(Opcional) O tipo de codificação dos parâmetros é application/x-www-form-urlencoded por padrão, mas também pode ser definido como multipart/form-data para métodos como POST.
params
Um objeto que mapeará dados de compartilhamento (das chaves: title, text, url e files do Web Share) para argumentos que o navegador transmitirá no URL (em method: 'GET') ou no corpo da solicitação usando a codificação selecionada.
.

Por exemplo, você pode definir para seu PWA se quer receber dados compartilhados (somente título e URL) adicionando ao manifesto:

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

No exemplo anterior, se algum app do sistema estiver compartilhando um URL com um título e o usuário selecionar seu PWA na caixa de diálogo, o navegador vai criar uma nova navegação para o /receive-share/?shared_title=AAA&shared_url=BBB da origem, em que AAA é o título compartilhado e BBB é o URL compartilhado. Você pode usar o JavaScript para ler esses dados da string window.location, analisando-os com o construtor URL.

O navegador usará o nome e o ícone do PWA do manifesto para alimentar a entrada de compartilhamento do sistema operacional. Não é possível escolher um conjunto diferente para esse fim.

Para ver exemplos mais detalhados e saber como receber arquivos, consulte Como receber dados compartilhados com a API Web Share Target.

Seleção de contatos

Compatibilidade com navegadores

  • Chrome: incompatível.
  • Edge: não compatível.
  • Firefox: incompatível.
  • Safari: incompatível.

Origem

Com a API Contact Picker, é possível solicitar que o dispositivo renderize uma caixa de diálogo nativa com todos os contatos do usuário para que ele possa escolher um ou mais. Seu PWA pode receber os dados que você quer desses contatos.

A API Contact Picker está disponível principalmente em dispositivos móveis, e tudo é feito pela interface navigator.contacts em plataformas compatíveis.

Você pode solicitar as propriedades disponíveis para consultar com navigator.contacts.getProperties() e selecionar um ou vários contatos com uma lista de propriedades desejadas.

Alguns exemplos de propriedades são name, email, address e tel. Quando você pedir que o usuário escolha um ou mais contatos, chame navigator.contacts.select(properties), transmitindo uma matriz de propriedades que você quer receber em troca.

O exemplo a seguir lista os contatos recebidos pelo seletor.

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