他のアプリとコンテンツを共有する
アプリ間でのコンテンツの共有は、ファイルの操作やコンテンツのコピーがデスクトップ オペレーティング システムよりも直感的ではないモバイル デバイスで普及していました。 たとえば、モバイルでは、テキスト メッセージを送信して画像を友人と共有するのが一般的です。 ただし、コンテンツの共有はモバイル デバイスに予約されていません。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 では、上記のコードによって共有ダイアログがトリガーされ、ユーザーは共有コンテンツを受け取るアプリを選択できます。 共有ダイアログを次に示します。
ユーザーが共有コンテンツを受け取るためにアプリを選択したら、選択した方法でアプリを処理するのはこのアプリ次第です。 たとえば、電子メール アプリでは、 を 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 つは次のとおりです。
- 最初に、API を
fetch
使用してリソースを要求します。 - 次に、返された応答を使用して新
File
しい を作成します。
その方法を次に示します。
async function getImageFileFromURL(imageURL, title) {
const response = await fetch(imageURL);
const blob = await response.blob();
return new File([blob], title, {type: blob.type});
}
上記のコードでは、
- 関数は
getImageFileFromURL
、URL を使用してイメージをフェッチします。 - 関数は
response.blob()
、イメージをバイナリ ラージ オブジェクト (BLOB) に変換します。 - このコードでは、BLOB を
File
使用して オブジェクトを作成します。
コンテンツの共有のデモ
PWAmp は、関数を使用してテキストとリンクを navigator.share
共有するデモ PWA です。
共有機能をテストするには:
[PWAmp] に移動します。
アドレス バーの右側にある [使用可能なアプリ] をクリックします 。PWA として ) をインストールします。
インストールされている PWAmp PWA で、ローカル オーディオ ファイルをインポートします (アプリ ウィンドウにドラッグします)。 たとえば、MicrosoftEdge/Demos リポジトリを複製した場合は、 (Demos repo > pwamp/songs ディレクトリ) 内のファイルの
.mp3
ローカル コピーがあります (例:C:\Users\username\GitHub\Demos\pwamp\songs
)。新しくインポートした曲の横にある [ 曲の操作 (...)] ボタンをクリックし、[ 共有] を選択します。 [Windows 共有 ] ダイアログが表示されます。
コンテンツを共有するアプリを選択します。
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
クエリ パラメーターを他の名前にマップできます。 次の例では、title
text
および url
クエリ パラメーターは、および address
にsubject
body
マップされています。
{
"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);
})());
}
});
上記のコードでは、
サービス ワーカーは要求をインターセプトします
POST
。何らかの方法でデータを使用します (コンテンツをローカルに格納する場合など)。
ユーザーを成功ページにリダイレクトします。 これにより、ネットワークがダウンしている場合でもアプリを動作させることができます。 アプリでは、コンテンツをローカルにのみ保存するか、接続が復元されたときに ( バックグラウンド同期を使用するなど) 後でサーバーにコンテンツを送信することもできます。
共有ファイルを処理する
アプリでは、共有ファイルを処理することもできます。 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);
})());
}
});