他のアプリとコンテンツを共有する

アプリ間でのコンテンツの共有は、ファイルの操作やコンテンツのコピーがデスクトップ オペレーティング システムよりも直感的ではないモバイル デバイスで普及していました。 たとえば、モバイルでは、テキスト メッセージを送信して画像を友人と共有するのが一般的です。 ただし、コンテンツの共有はモバイル デバイスに予約されていません。Windows 上のアプリ間でも共有できます。

コンテンツの共有には 2 つの方向があり、双方向はプログレッシブ Web Apps (PWA) によって処理できます。

方向 説明
コンテンツの共有 コンテンツを共有するために、PWA はコンテンツ (テキスト、リンク、ファイルなど) を生成し、共有コンテンツをオペレーティング システムに渡します。 オペレーティング システムを使用すると、ユーザーは、そのコンテンツを受信するために使用するアプリを決定できます。
共有コンテンツの受信 コンテンツを受信するために、PWA はコンテンツ ターゲットとして機能します。 PWA は、コンテンツ共有ターゲットとしてオペレーティング システムに登録されます。

共有ターゲットとして登録する PWA は、ネイティブに OS に統合され、ユーザーとのエンゲージメントが高いと感じます。

コンテンツの共有

PWA は 、Web 共有 API を使用して、オペレーティング システム共有ダイアログの表示をトリガーできます。

注:

Web 共有は HTTPS 経由で提供されるサイト (PWA の場合) でのみ機能し、ユーザー アクションに応答して呼び出すことができます。

リンク、テキスト、ファイルなどのコンテンツを共有するには、次に示すように 関数を navigator.share 使用します。 関数は navigator.share 、次のプロパティの少なくとも 1 つを持つオブジェクトを受け入れます。

  • title: 共有コンテンツの短いタイトル。
  • text: 共有コンテンツの詳細な説明。
  • url: 共有するリソースのアドレス。
  • files: 共有するファイルの配列。
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);
  });
}

上記のコードでは、まず、ブラウザーが Web 共有をサポートしているかどうかをテストして、定義されているかどうかをテストnavigator.shareしてチェックします。 関数は navigator.share 、共有が成功したときに解決され、エラーが発生したときに拒否する Promise オブジェクトを返します。

Promise はここで使用されるため、上記のコードを関数として async 次のように書き換えることができます。

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);
  }
}

Windows では、上記のコードによって共有ダイアログがトリガーされ、ユーザーは共有コンテンツを受け取るアプリを選択できます。 共有ダイアログを次に示します。

Windows の [共有] ダイアログ

ユーザーが共有コンテンツを受け取るためにアプリを選択したら、選択した方法でアプリを処理するのはこのアプリ次第です。 たとえば、電子メール アプリでは、 を title 電子メールの件名として使用し、 を text 電子メール本文として使用します。

ファイルの共有

関数は navigator.share 、他のアプリとファイルを files 共有する配列も受け入れます。

共有する前に、共有ファイルがブラウザーでサポートされているかどうかをテストすることが重要です。 共有ファイルがサポートされているかどうかをチェックするには、 関数を使用しますnavigator.canShare

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

共有オブジェクト メンバーは files 、オブジェクトの File 配列である必要があります。 ファイル インターフェイスの詳細については、こちらをご覧ください。

オブジェクトを構築 File する方法の 1 つは次のとおりです。

  1. 最初に、API を fetch 使用してリソースを要求します。
  2. 次に、返された応答を使用して新 Fileしい を作成します。

その方法を次に示します。

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

上記のコードでは、

  1. 関数は getImageFileFromURL 、URL を使用してイメージをフェッチします。
  2. 関数は response.blob() 、イメージをバイナリ ラージ オブジェクト (BLOB) に変換します。
  3. このコードでは、BLOB を File 使用して オブジェクトを作成します。

コンテンツの共有のデモ

PWAmp は、関数を使用してテキストとリンクを navigator.share 共有するデモ PWA です。

共有機能をテストするには:

  1. [PWAmp] に移動します。

  2. アドレス バーの右側にある [使用可能なアプリ] をクリックします 。PWA として PWAmp をインストールするには、[インストール] ボタン (PWA の [利用可能なアプリ]、[インストール] アイコン) をインストールします。

  3. インストールされている PWAmp PWA で、ローカル オーディオ ファイルをインポートします (アプリ ウィンドウにドラッグします)。 たとえば、MicrosoftEdge/Demos リポジトリを複製した場合は、 (Demos repo > pwamp/songs ディレクトリ) 内のファイルの.mp3ローカル コピーがあります (例: C:\Users\username\GitHub\Demos\pwamp\songs)。

  4. 新しくインポートした曲の横にある [ 曲の操作 (...)] ボタンをクリックし、[ 共有] を選択します。 [Windows 共有 ] ダイアログが表示されます。

    [Windows 共有] ダイアログボックスで、共有コンテンツを受け取るアプリを選択します

  5. コンテンツを共有するアプリを選択します。

PWAmp ソース コードは GitHub にあります。 PWAmp アプリは、 app.js ソース ファイル内の Web 共有 API を使用します。

共有コンテンツの受信

Web 共有ターゲット API を使用すると、PWA を登録して、システム共有ダイアログにアプリとして表示できます。 その後、PWA は Web Share Target API を使用して、他のアプリから送信される共有コンテンツを処理できます。

注:

共有ターゲットとして登録できるのは、インストールされている PWA のみです。

ターゲットとして登録する

共有コンテンツを受信するには、まず PWA を共有ターゲットとして登録します。 登録するには、マニフェスト メンバーを使用します share_target 。 アプリのインストール時に、オペレーティング システムはメンバーを share_target 使用して、アプリをシステム共有ダイアログに含めます。 オペレーティング システムは、コンテンツを共有するために、アプリがユーザーによって選択されたときに何を行うかを認識します。

メンバーには share_target 、システムが共有コンテンツをアプリに渡すために必要な情報が含まれている必要があります。 次のマニフェスト コードを考えてみましょう。

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

ユーザーが共有コンテンツのターゲットとしてアプリを選択すると、PWA が起動します。 GETプロパティで指定された URL に対して HTTP 要求がaction行われます。 共有データは、、text、および url クエリ パラメーターとしてtitle渡されます。 次の要求が行われます。 /handle-shared-content/?title=shared title&text=shared text&url=shared url

他のクエリ パラメーター名を使用する既存のコードがある場合は、既定 titleの 、、 textおよび url クエリ パラメーターを他の名前にマップできます。 次の例では、titletextおよび url クエリ パラメーターは、および addresssubjectbodyマップされています。

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

GET 共有データを処理する

PWA コードの GET 要求で共有されるデータを処理するには、コンストラクターを URL 使用してクエリ パラメーターを抽出します。

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');
});

POST 共有データを処理する

共有データがアプリに格納されているコンテンツの一部を更新するなど、何らかの方法でアプリを変更する場合は、 メソッドを POST 使用し、 でエンコードの種類 enctypeを定義する必要があります。

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

POST HTTP 要求には、 としてmultipart/form-dataエンコードされた共有データが含まれています。 このデータには、サーバー側のコードを使用して HTTP サーバー上でアクセスできますが、ユーザーがオフラインの場合は機能しません。 エクスペリエンスを向上させるために、次のようにイベント リスナーを使用して、サービス ワーカー内のデータに fetch アクセスできます。

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);
        })());
    }
});

上記のコードでは、

  1. サービス ワーカーは要求をインターセプトします POST

  2. 何らかの方法でデータを使用します (コンテンツをローカルに格納する場合など)。

  3. ユーザーを成功ページにリダイレクトします。 これにより、ネットワークがダウンしている場合でもアプリを動作させることができます。 アプリでは、コンテンツをローカルにのみ保存するか、接続が復元されたときに ( バックグラウンド同期を使用するなど) 後でサーバーにコンテンツを送信することもできます。

共有ファイルを処理する

アプリでは、共有ファイルを処理することもできます。 PWA 内のファイルを処理するには、 メソッドとエンコードの POST 種類を使用する multipart/form-data 必要があります。 さらに、アプリで処理できるファイルの種類を宣言する必要があります。

{
    "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"]
                }
            ]
        }
    }
}

上記のマニフェスト コードは、アプリがさまざまな MIME 型のテキスト ファイルを受け入れることをシステムに指示します。 などの .txtファイル名拡張子を配列に accept 渡すこともできます。

共有ファイルにアクセスするには、前のような要求 formData を使用し、次のように を FileReader 使用してコンテンツを読み取ります。

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);
        })());
    }
});

関連項目