次の方法で共有


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

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

コンテンツの共有には 2 つの方向があり、双方向はプログレッシブ Web アプリ (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. まず、 fetch API を使用してリソースを要求します。
  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 リポジトリを複製した場合、C:\Users\username\GitHub\Demos\pwamp\songsなどの (Demos リポジトリ > pwamp/songs ディレクトリ) に.mp3 ファイルのローカル コピーがあります。

  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 HTTP 要求は、action プロパティで指定された URL に対して行われます。 共有データは、 titletext、および url クエリ パラメーターとして渡されます。 次の要求が行われます: /handle-shared-content/?title=shared title&text=shared text&url=shared url

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

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

関連項目