Compartilhar conteúdo com outros aplicativos

O compartilhamento de conteúdo entre aplicativos tornou-se popular por dispositivos móveis em que manipular arquivos ou copiar conteúdo é menos intuitivo do que em sistemas operacionais de área de trabalho. Por exemplo, no celular, é comum compartilhar uma imagem com um amigo enviando uma mensagem de texto. Mas o compartilhamento de conteúdo não é reservado para dispositivos móveis; também é possível compartilhar entre aplicativos no Windows.

Há duas direções para compartilhar conteúdo e ambas as direções podem ser tratadas por PWAs (Progressive Aplicativos Web):

Direção Descrição
Compartilhando conteúdo Para compartilhar conteúdo, um PWA gera conteúdo (como texto, links ou arquivos) e distribui o conteúdo compartilhado para o sistema operacional. O sistema operacional permite que o usuário decida qual aplicativo deseja usar para receber esse conteúdo.
Recebimento de conteúdo compartilhado Para receber conteúdo, um PWA atua como um destino de conteúdo. O PWA é registrado no sistema operacional como um destino de compartilhamento de conteúdo.

As PWAs que se registram como destinos de compartilhamento se sentem integradas nativamente ao sistema operacional e são mais atraentes para os usuários.

Compartilhando conteúdo

As PWAs podem usar a API do Compartilhamento Web para disparar a exibição da caixa de diálogo compartilhamento do sistema operacional.

Observação

O compartilhamento da Web funciona apenas em sites atendidos por HTTPS (que é o caso de PWAs) e só pode ser invocado em resposta a uma ação do usuário.

Para compartilhar conteúdo como links, texto ou arquivos, use a navigator.share função, conforme mostrado abaixo. A navigator.share função aceita um objeto que deve ter pelo menos uma das seguintes propriedades:

  • title: um título curto para o conteúdo compartilhado.
  • text: uma descrição mais longa para o conteúdo compartilhado.
  • url: o endereço de um recurso a ser compartilhado.
  • files: uma matriz de arquivos a serem compartilhados.
function shareSomeContent(title, text, url) {
  if (!navigator.share) {
    return;
  }

  navigator.share({title, text, url}).then(() => {
    console.log('The content was shared successfully');
  }).catch(error => {
    console.error('Error sharing the content', error);
  });
}

No código acima, primeiro marcar se o navegador dá suporte ao compartilhamento da Web, testando se navigator.share for definido. A navigator.share função retorna um objeto Promise que é resolvido quando o compartilhamento é bem-sucedido e rejeita quando ocorreu um erro.

Como uma Promessa é usada aqui, o código acima pode ser reescrito como uma async função, da seguinte maneira:

async function shareSomeContent(title, text, url) {
  if (!navigator.share) {
    return;
  }

  try {
    await navigator.share({title, text, url});
    console.log('The content was shared successfully');
  } catch (e) {
    console.error('Error sharing the content', e);
  }
}

No Windows, o código acima disparará a caixa de diálogo de compartilhamento, permitindo que o usuário escolha um aplicativo para receber o conteúdo compartilhado. A caixa de diálogo de compartilhamento é mostrada abaixo:

A caixa de diálogo de compartilhamento no Windows

Depois que o usuário tiver selecionado um aplicativo para receber o conteúdo compartilhado, cabe a este aplicativo lidar com ele da maneira que ele escolher. Por exemplo, um aplicativo de email pode usar o title como assunto de email e usar o text como o corpo do email.

Compartilhamento de arquivos

A navigator.share função também aceita uma files matriz para compartilhar arquivos com outros aplicativos.

É importante testar se o compartilhamento de arquivos tem suporte pelo navegador antes de compartilhá-los. Para marcar se há suporte para o compartilhamento de arquivos, use a navigator.canShare função:

function shareSomeFiles(files) {
  if (navigator.canShare && navigator.canShare({files})) {
    console.log('Sharing files is supported');
  } else {
    console.error('Sharing files is not supported');
  }
}

O files membro do objeto de compartilhamento deve ser uma matriz de File objetos. Saiba mais sobre a interface Arquivo.

Uma maneira de construir File objetos é:

  1. Primeiro, use a fetch API para solicitar um recurso.
  2. Em seguida, use a resposta retornada para criar um novo File.

Essa abordagem é mostrada abaixo.

async function getImageFileFromURL(imageURL, title) {
  const response = await fetch(imageURL);
  const blob = await response.blob();
  return new File([blob], title, {type: blob.type});
}

No código acima:

  1. A getImageFileFromURL função busca uma imagem usando uma URL.
  2. A response.blob() função converte a imagem em um BLOB (objeto binário grande).
  3. O código cria um File objeto usando o BLOB.

Demonstração de compartilhamento de conteúdo

PWAmp é uma demonstração PWA que usa a navigator.share função para compartilhar texto e links.

Para testar o recurso de compartilhamento:

  1. Vá para PWAmp.

  2. No lado direito da barra de endereços, clique no Aplicativo disponível. Instalar o botão (ícone PWA 'App available, Install' ) para instalar o PWAmp como um PWA.

  3. No PWA pwamp instalado, importe um arquivo de áudio local (arrastando-o para a janela do aplicativo). Por exemplo, se você clonou o repositório MicrosoftEdge/Demos , terá uma cópia local de .mp3 arquivos no (diretório Demos repo > pwamp/songs), como C:\Users\username\GitHub\Demos\pwamp\songs.

  4. Ao lado da música recém-importada, clique no botão Ações de música (...) e selecione Compartilhar. A caixa de diálogo Windows Share é exibida:

    A caixa de diálogo Windows Share, para escolher qual aplicativo recebe o conteúdo compartilhado

  5. Escolha um aplicativo no qual compartilhar o conteúdo.

Você pode encontrar o código-fonte PWAmp no GitHub. O aplicativo PWAmp usa a API de Compartilhamento Web no arquivo de origemapp.js.

Recebimento de conteúdo compartilhado

Usando a API de Destino do Compartilhamento Web , um PWA pode se registrar para ser exibido como um aplicativo na caixa de diálogo compartilhamento do sistema. Em seguida, o PWA pode usar a API de Destino do Compartilhamento Da Web para lidar com o conteúdo compartilhado proveniente de outros aplicativos.

Observação

Somente PWAs instaladas podem se registrar como destinos de compartilhamento.

Registrar-se como um destino

Para receber conteúdo compartilhado, a primeira coisa a fazer é registrar seu PWA como um destino de compartilhamento. Para se registrar, use o membro do share_target manifesto. Após a instalação do aplicativo, o sistema operacional usa o share_target membro para incluir seu aplicativo na caixa de diálogo compartilhamento do sistema. O sistema operacional sabe o que fazer quando seu aplicativo é escolhido pelo usuário para compartilhar o conteúdo.

O share_target membro deve conter as informações necessárias para que o sistema passe o conteúdo compartilhado para seu aplicativo. Considere o seguinte código de manifesto:

{
    "share_target": {
        "action": "/handle-shared-content/",
        "method": "GET",
        "params": {
            "title": "title",
            "text": "text",
            "url": "url",
        }
    }
}

Quando seu aplicativo é selecionado pelo usuário como o destino do conteúdo compartilhado, o PWA é iniciado. Uma GET solicitação HTTP é feita à URL especificada pela action propriedade. Os dados compartilhados são passados como parâmetros title, texte url consulta. A seguinte solicitação é feita: /handle-shared-content/?title=shared title&text=shared text&url=shared url.

Se você tiver um código existente que usa outros nomes de parâmetro de consulta, poderá mapear os parâmetros padrão title, texte url consultar para seus outros nomes. No exemplo a seguir, os titleparâmetros , texte url de consulta são mapeados para subject, bodye address:

{
    "share_target": {
        "action": "/handle-shared-content/",
        "method": "GET",
        "params": {
            "title": "subject",
            "text": "body",
            "url": "address",
        }
    }
}

Manipular dados compartilhados get

Para manipular os dados compartilhados sobre a solicitação GET no código PWA, use o URL construtor para extrair os parâmetros de consulta:

window.addEventListener('DOMContentLoaded', () => {
    console url = new URL(window.location);

    const sharedTitle = url.searchParams.get('title');
    const sharedText = url.searchParams.get('text');
    const sharedUrl = url.searchParams.get('url');
});

Manipular dados compartilhados do POST

Se os dados compartilhados forem destinados a alterar seu aplicativo de alguma forma, como atualizar parte do conteúdo armazenado no aplicativo, você deverá usar o POST método e definir um tipo de codificação com enctype:

{
    "share_target": {
        "action": "/post-shared-content",
        "method": "POST",
        "enctype": "multipart/form-data",
        "params": {
            "title": "title",
            "text": "text",
            "url": "url",
        }
    }
}

A POST solicitação HTTP contém os dados compartilhados, codificados como multipart/form-data. Você pode acessar esses dados no servidor HTTP usando o código do lado do servidor, mas isso não funcionará quando o usuário estiver offline. Para fornecer uma experiência melhor, você pode acessar os dados no trabalho de serviço, usando um fetch ouvinte de eventos, da seguinte maneira:

self.addEventListener('fetch', event => {
    const url = new URL(event.request.url);

    if (event.request.method === 'POST' && url.pathname === '/post-shared-content') {
        event.respondWith((async () => {
            const data = await event.request.formData();

            const title = data.get('title');
            const text = data.get('text');
            const url = data.get('url');

            // Do something with the shared data here.

            return Response.redirect('/content-shared-success', 303);
        })());
    }
});

No código acima:

  1. O funcionário do serviço intercepta a solicitação POST .

  2. Usa os dados de alguma forma (como armazenar o conteúdo localmente).

  3. Redireciona o usuário para uma página de sucesso. Dessa forma, o aplicativo pode funcionar mesmo que a rede esteja desativada. O aplicativo pode optar por armazenar apenas o conteúdo localmente ou enviar o conteúdo para o servidor posteriormente, quando a conectividade for restaurada (como usando a Sincronização em Segundo Plano).

Manipular arquivos compartilhados

Os aplicativos também podem lidar com arquivos compartilhados. Para manipular arquivos em seu PWA, você deve usar o POST método e o multipart/form-data tipo de codificação. Além disso, você deve declarar os tipos de arquivos que seu aplicativo pode manipular.

{
    "share_target": {
        "action": "/store-code-snippet",
        "method": "POST",
        "enctype": "multipart/form-data",
        "params": {
            "title": "title",
            "files": [
                {
                    "name": "textFile",
                    "accept": ["text/plain", "text/html", "text/css", 
                               "text/javascript"]
                }
            ]
        }
    }
}

O código de manifesto acima informa ao sistema que seu aplicativo pode aceitar arquivos de texto com vários tipos MIME. Extensões de nome de arquivo, como .txt, também podem ser passadas na accept matriz.

Para acessar o arquivo compartilhado, use a solicitação formData como antes e use uma FileReader para ler o conteúdo, da seguinte maneira:

self.addEventListener('fetch', event => {
    const url = new URL(event.request.url);

    if (event.request.method === 'POST' && url.pathname === '/store-code-snippet') {
        event.respondWith((async () => {
            const data = await event.request.formData();

            const filename = data.get('title');
            const file = data.get('textFile');

            const reader = new FileReader();
            reader.onload = function(e) {
                const textContent = e.target.result;

                // Do something with the textContent here.

            };
            reader.readAsText(file);

            return Response.redirect('/snippet-stored-success', 303);
        })());
    }
});

Confira também