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. Há pouco tempo, eles nem podiam ser instalados. Felizmente, isso mudou, e agora podemos aproveitar essa integração para adicionar recursos úteis aos nossos PWAs. Vamos conferir algumas dessas opções.
Como trabalhar com o sistema de arquivos
Um fluxo de trabalho típico de usuário usando arquivos é assim:
- Escolha um arquivo ou uma pasta no dispositivo e abra diretamente.
- Faça alterações nesses arquivos ou pastas e salve as mudanças diretamente.
- Crie novos arquivos e pastas.
Antes da API File System Access, os apps da Web não podiam fazer isso. Abrir arquivos exigia um upload de arquivo, salvar mudanças exigia que os usuários fizessem o download deles, e a Web não tinha acesso algum 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 um clique no botão. Confira o restante da configuração para abrir um arquivo:
- Capture o handle de arquivo da API do seletor de arquivos do acesso ao sistema de arquivos. Isso mostra informações básicas sobre o arquivo.
- Usando o método
getFile()
do identificador, você terá um tipo especial deBlob
chamadoFile
, que inclui outras propriedades somente leitura (como nome e data da última modificação) sobre o arquivo. Como ele é um Blob, os métodos Blob podem ser chamados nele, comotext()
, para acessar 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 as alterações em um arquivo, você também precisa de um gesto do usuário. Em seguida:
- Use o identificador de arquivo para criar um
FileSystemWritableFileStream
. - Faça alterações no stream. Isso não atualiza o arquivo no local. Em vez disso, um arquivo temporário é criado.
- Por fim, quando terminar de fazer as mudanças, feche a transmissão, o que muda o status delas de temporário para permanente.
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 no app, mas e o contrário? Os usuários querem definir o app favorito como padrão para abrir arquivos. A API de processamento de arquivos é uma API experimental que permite que os PWAs instalados: se registrem como um gerenciador de arquivos no dispositivo de um usuário, especificando o tipo MIME e a extensão de arquivo com suporte ao PWA no manifesto do app da Web. É possível especificar ícones de arquivo personalizados para as extensões compatíveis.
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 nele. Confira um exemplo de configuração de manifesto para que um PWA leia arquivos de texto:
...
"file_handlers": [
{
"action": "/open-file",
"accept": {
"text/*": [".txt"]
}
}
]
...
Processamento de URL
Com o processamento de URL, o PWA pode capturar links que fazem parte do escopo do sistema operacional e renderizá-los em uma janela de PWA, em vez da guia padrão do navegador. Por exemplo, se você receber uma mensagem com um link para a PWA ou clicar em um link direto (um URL que aponta para um conteúdo específico) na PWA, o conteúdo será aberto em uma janela independente.
Esse comportamento está disponível automaticamente no Android quando o WebAPK é usado, por exemplo, quando os usuários instalam um PWA com o Chrome. Não é possível capturar URLs de PWAs instalados no iOS e iPadOS pelo Safari.
Para navegadores de computador, a comunidade de navegadores da Web criou uma nova especificação. Essa especificação é experimental e adiciona um novo membro de arquivo de manifesto: url_handlers
. Essa propriedade espera uma matriz de origens que a PWA quer capturar. A origem da sua PWA será concedida automaticamente, e todas as outras origens precisam aceitar esse processamento por um arquivo chamado web-app-origin-association
.
Por exemplo, se o manifesto do PWA estiver hospedado no web.dev e você quiser adicionar a origem app.web.dev, ele vai ficar assim:
"url_handlers": [
{"origin": "https://app.web.dev"},
]
Nesse caso, o navegador vai verificar se um arquivo existe em app.web.dev/.well-known/web-app-origin-association
, aceitando o processamento de URL do URL de escopo da PWA. O desenvolvedor precisa criar esse arquivo. No exemplo abaixo, o arquivo tem esta aparência:
{
"web_apps": [
{
"manifest": "/mypwa/app.webmanifest",
"details": {
"paths": [ "/*" ]
}
}
]
}
Processamento de protocolos de URL
O processamento de URL funciona com URLs de protocolo https
padrão, mas é possível usar esquemas de URI personalizados, como pwa://
. Em vários sistemas operacionais, os apps instalados ganham essa capacidade ao registrarem os esquemas.
Para PWA, esse recurso é ativado usando a API URL Protocol Handler, disponível apenas em dispositivos de computador. Só é possível permitir protocolos personalizados para dispositivos móveis distribuindo o app PWA em lojas de apps.
Para fazer o registro, use o método registerProtocolHandler() ou o membro protocol_handlers
no manifesto, com o esquema e o URL que você quer carregar no contexto da PWA, como:
...
{
"protocol_handlers": [
{
"protocol": "web+pwa",
"url": "/from-protocol?value=%s"
},
]
}
...
Você pode encaminhar o URL from-protocol
para o gerenciador correto e receber a string de consulta value
na PWA. O %s
é um marcador de posição para o URL escapado que acionou a operação. Portanto, se você tiver um link em algum lugar, como <a href="web+pwa://testing">
, o PWA vai abrir /from-protocol?value=testing
.
Ligar para outros apps
É possível usar esquemas de URI para se conectar a qualquer outro app instalado (PWA ou não) nos dispositivos dos usuários em todas as plataformas. Basta criar um link ou usar navigator.href
e apontar para o esquema de URI desejado, transmitindo os argumentos no formulário de URL com escape.
Você pode usar esquemas padrão conhecidos, como tel:
para ligações, mailto:
para envio de e-mails ou sms:
para mensagens de texto. Também é possível aprender sobre outros esquemas de URL de apps, por exemplo, de mensagens, mapas, navegação, reuniões on-line, redes sociais e app stores conhecidos.
Compartilhamento na Web
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.
É possível compartilhar um objeto que contém:
- Texto (propriedades
title
etext
) - Um URL (propriedade
url
) - Arquivos (propriedade
files
).
Para verificar se o dispositivo atual pode compartilhar dados simples, como texto, verifique a presença do método navigator.share()
. Para compartilhar arquivos, verifique a presença do método navigator.canShare()
.
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.
Destino do compartilhamento na Web
A API Web Share Target permite que o PWA seja o destino de uma operação de compartilhamento de outro app no dispositivo, seja ele um PWA ou não. Seu PWA recebe os dados compartilhados por outro app.
No momento, ele está disponível no Android com WebAPK e ChromeOS e só funciona depois que o usuário instala a PWA. O navegador registra o destino de compartilhamento no sistema operacional quando o app é instalado.
Você configura o destino de compartilhamento da Web no manifesto com o membro share_target
definido no rascunho da especificação do destino de compartilhamento da Web. share_target
é definido como um objeto com algumas propriedades:
action
- URL que será carregado em uma janela de PWA que deve receber os dados compartilhados.
method
O método do verbo HTTP - será usado para a ação, como
GET
,POST
ouPUT
. enctype
- (Opcional) O tipo de codificação dos parâmetros é
application/x-www-form-urlencoded
por padrão, mas também pode ser definido comomultipart/form-data
para métodos comoPOST
. params
- Um objeto que mapeia os dados compartilhados (das chaves:
title
,text
,url
efiles
do Compartilhamento na Web) para argumentos que o navegador vai transmitir no URL (emmethod: 'GET'
) ou no corpo da solicitação usando a codificação selecionada.
Por exemplo, você pode definir para o PWA que quer receber dados compartilhados (somente título e URL) adicionando o seguinte ao manifesto:
...
"share_target": {
"action": "/receive-share/",
"method": "GET",
"params": {
"title": "shared_title",
"url": "shared_url"
}
}
...
No exemplo anterior, se qualquer app no sistema estiver compartilhando um URL com um título e o usuário escolher sua PWA na caixa de diálogo, o navegador vai criar uma nova navegação para a /receive-share/?shared_title=AAA&shared_url=BBB
da origem, em que AAA é o título compartilhado e BBB é o URL compartilhado. É possível usar o JavaScript para ler esses dados da string window.location
analisando-a com o construtor URL
.
O navegador vai 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 essa finalidade.
Para conferir exemplos mais detalhados e saber como receber arquivos, consulte Receber dados compartilhados com a API Web Share Target.
Seleção de contatos
Com a API Contact Picker, você pode 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. Assim, a 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.
É possível solicitar as propriedades disponíveis para consulta com navigator.contacts.getProperties()
e solicitar uma seleção de contatos única ou múltipla com uma lista de propriedades desejadas.
Alguns exemplos de propriedades são name
, email
, address
e tel
. Quando você pede ao usuário para escolher um ou mais contatos, é possível chamar 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
- A API File System Access: simplificando o acesso a arquivos locais
- Permitir que aplicativos da Web instalados sejam processadores de arquivos
- Processar arquivos em apps Web progressivos
- Integrar a interface de compartilhamento do SO com a API Web Share
- Compartilhar conteúdo com outros apps
- Receber dados compartilhados com a API Web Share Target
- Um seletor de contatos para a Web