2012年01月07日
マルチデバイス連携を実現する WebIntents 〜基本と使い方編〜
新年明けましておめでとうございます。本年も宜しくお願いします。
さて、今年最初のPOSTは、僕が今一番興味を持っているAPIの "Web Intents" について取り上げます。
この、"Web Intents"は、Androidの "Intent" に非常に良く似た仕組みで、異なるWebアプリケーションを自由に連携することを可能とするAPIです。Webサイトの不足機能に対し、他のWebアプリの機能を利用することが可能になるため、スピーディーなWebアプリの開発を実現してくれます。利用するユーザーにとっても、手慣れたWebアプリを利用できるメリットが有ります。
このAPIの更に興味深いところは、
- Device機能の利用
- デバイス内の固有の機能(カメラや、住所録など)をブラウザから利用する。
- Web of things
- スマートフォンやテレビなどのマルチデバイス連携サービスをWebで実現する。あらゆるものが繋がるWeb
Android Intentによく似たAPIが、「Device機能やマルチデバイス連携サービス実現に必須となる」といっても、イマイチピンと来ないかもしれません(僕も最初はピンときませんでした)。この点については、次回のエントリーで紹介することにして、今日のエントリーでは "Web Intents" の基本的な考え方とその使い方について紹介します。
What's Web Intents?
Web Intentsは、先にも述べたように Android Intent のように、Webアプリケーションどうしを連携するAPIです。Webサイトから Web Intents のAPI を呼び出すと、pickerウィンドウが立ち上がり、登録済みのWebアプリケーションがリスト表示されます。ユーザーは、その中から任意のWebアプリを選択し、そのサービスを利用することができます。
例えば、現状のWebページで mailto: を指定すると、OSに登録されているメーラーが自動起動しますが、これを「GMailを使いたいな」と思ったことがある人は多いのではないかと思います。このようなケースで Web Intents を使うと、ユーザーは自分の使いたいWeb Mail Serviceを選択できるようになるといった感じです。例えば、GMailが立ち上がり、送信先アドレスなどが自動入力された状態で、メールの新規作成画面が表示されるといった具合。異なるWebサイト間で、データを受け渡し、連携することが可能になるわけです。
これまででも、複数のWebアプリケーションを連携させることは可能でした。例えば、ガジェットサービスのように、他のWebサイトのコンテンツを iframe で埋め込み、HTML5 Messaging ( PostMessage() ) を使うことで、異なる Webアプリ間でデータ連携を行うことは可能です。
しかしながら、連携するWebアプリは、サイトの開発者が指定する形態となっており、利用者は連携するWebアプリを基本的には選択することは出来ませんでした。先程のメールの例で言えば、サイトの開発者が GMail を選択すると、ユーザーは Yahoo!メール を使いたくても、それを直接利用することは出来ないのです。
このような状況を解決するものが、Web Intents です。すなわち、連携する Webアプリの選択権を開発者から利用者に渡し、その時々のユーザーの嗜好や状況に応じて、自由にWebアプリを選択することが可能になります。そして、この特徴が、Web アプリによるデバイス機能の利用や、マルチデバイス連携のシナリオを、現実的なものとします(この辺りの詳細は、次回説明します)。

How to use Web Intents API
それでは、具体的な使い方について説明します。なお、以下の説明は、執筆時点の仕様に基づくもので、今後変更になる可能性があることをご承知ください。
Registration
Web Intentsでは、まず連携するWebアプリをブラウザに登録する必要があります。Android Intentであれば、アプリをインストールするときに登録されるわけですが、Webアプリではそういうわけにはいきません。このため、登録したいWebサイトの<head>内に、<intent>タグを書くことで、ブラウザに、そのサイトを登録します。具体的には、以下のような手順です。
- Web Intentとして利用して欲しい Web サイトに <intent> を記述する。
- 利用者が、上記のWebサイトにアクセスする
- ブラウザは、<intent>内の情報を見て、ブラウザにそのサイトを Web Intent として登録する。
<intent action="http://webintents.org/share" type="image/*" title="image share" href="share.html" disposition="window" />
- action (required)
- Webアプリが「何の機能(動作)を提供するか」を示す。任意の文字列を指定可能。上の例はスキーマURLとなっており、共有機能を提供することを現している。なお、http://webintents.org/shareでは、このスキーマURLを用いる場合の仕様が記述されている。
- type (optional)
- Webアプリが「何を扱えるか」を示す。任意の文字列を指定可能。上の例では MIME type を示しており、あらゆるフォーマットの画像を扱えることを意味している。
- title (optional)
- このWebアプリのタイトル。Web Intentsのピッカーに、このタイトルが表示される。
- href (optional)
- Intent登録するWebアプリのURL。上のIntentタグが、http://example.com/ に記述されている場合、http://example.com/share.html がIntentのサイトとして登録される
- disposition (default="window")
- Webアプリが、どのように表示されるかを示す。windowとinlineを指定可能となっており、windowの場合は、異なるWindowに表示される。inlineの場合は、ピッカー内に表示される。
Invocation
次は、あるWebアプリから、Web Intents を利用する手順です。他のWebアプリに処理を任せたい type と action を指定して、Web Intentsを呼び出し、ピッカーを表示します。
まず、以下の例のように Intent オブジェクトのインスタンスを生成します。
var intent = new Intent( "http://webintents.org/share", ‘image/png’, 'http://hoge.com/image.png');これは、画像を共有する場合を例としています。コンストラクタの引数は、それぞれ以下のようになります。
- 第1引数: action (required)
- Intentに対して依頼する action を指定する。任意の文字列を指定可能。上の例では、スキーマURLにより、share(共有)を指定している
- 第2引数: type (required)
- Intentに処理を依頼するデータの type を指定する。任意の文字列を指定可能。上の例では、MIME type(image/png)を用い、png形式の画像を用いることを示している
- 第3引数; data (required)
- Intentに渡すデータを指定する。任意のObjectを指定可能(structured cloneアルゴリズムが適用される)。ただし、引き渡すデータの形式は、action と type のペアごとに固有のフォーマットで渡す必要がある。上の例では、その仕様がスキーマURLの http://webintents.org/share で規定されているため、その仕様に則り、画像のURLを指定している。(※ canvasなどを用い、data-urlを生成して、引き渡すことも可能)
window.navigator.startActivity(intent, onSuccess, onError);
- intent (required)
- 生成した Intent オブジェクトのインスタンスを指定
- onSuccess (optional)
- Intentからデータが返ってきた時(Intent側でpostResult()を呼んだ時)の callback 関数。この関数の第一引数に Intent からのデータが格納される。
- onError (optional)
- Intentで、処理が失敗したとき(Intent側でpostFailure()を呼んだ時)の callback 関数。この関数の第一引数に Intent からのデータが格納される。
Intentで呼び出された際のデータの処理方法
ピッカー経由で、Webアプリが呼ばれると、
window.intentに、各種データが格納されています。例えば
window.intent.dataに、呼び出し側から指定されたデータが格納されていますので、それに対する処理を行った後、
window.intent.postResult(some_data);として、処理後のデータを指定して intent.postResult() を呼ぶことで、データが呼び出し側に戻ります(startActivity()の第二引数で指定した関数が呼ばれます)。この時のデータの形式は、action と type のペアで規定される仕様に従います(上の例ではhttp://webintents.org/shareに、この仕様が記載されています)。
なお、処理に失敗した場合は、intent.postFailure()を呼んでください。呼び出し側に処理が戻り、startActivity()の第三引数で指定した関数が呼ばれます。
エミュレーションライブラリ
現在、Web Intentsをサポートするブラウザはありませんが、これをエミュレーションするライブラリが公開されています。Intentを呼び出す側、呼び出される側双方で、以下のJavascriptを読み込むことで、Web Intents を試すことが出来ます。
<script src="http://webintents.org/webintents.min.js"></script>
サンプルサイト
http://webintents.cloudfoundry.com/に、Web Intentsのサンプルサイトを作ってみました。

このページの head タグ内には、
<intent action="http://webintents.org/shorten" type="text/uri-list" href="shorten" title="Link Shortener(test)" /> <intent action="http://webintents.org/share" type="image/*" href="imageshare" title="Image Share(test)" />と、二つの intent タグが記載されており、http://webintents.cloudfoundry.com/shortenで URL の短縮化サービス(shorten)を、http://webintents.cloudfoundry.com/shareで、画像の共有サービスをWeb Intentsとして登録しています。(注記:エミュレーションライブラリでは、現状 http://webintents.org の Origin の localStorage に登録しています。)
ここで、例えば "shorten" と書かれたボタンをクリックすると、以下のコードが実行されます。
$("#urlshortner button").click(function(){
var url = $("#urlshortner input").val();
var intent = new Intent(
"http://webintents.org/shorten",
"text/uri-list",
url);
window.navigator.startActivity(intent, function(data) {
$("#urlshortner .out").text(data);
});
});
ここでは、action = http://webintents.org/shorten, type = text/uri-list で、インスタンス(intent)を生成し、startActivity()で、Web Intentsを呼び出しています。ここで、この type と action に対して、先に示したように "http://webintents.cloudfoundry.com/shorten" が登録されていますので、ピッカーにはこのURLが表示されます。このリンクをクリックすると、処理がこのサイトに引き継がれます。

http://webintents.cloudfoundry.com/shorten では、最初に
var url = window.intent && window.intent.data || null;と、Web Intents で渡されたデータを取得し、
var shorten = url.length > 8 ? url.slice(0,8) : url;と、渡されたURLを最初の8文字に短縮します(無茶苦茶インチキですが、まぁサンプルということでご容赦ください (^^;) )。

ここで、"back to caller"のボタンをクリックすると、以下のコードにより、データが呼び出し側に戻されます。
window.intent.postResult(shorten); setTimeout( window.close, 500);postResult()で、短縮後のURLデータを呼び出し側に戻し、window.close() を呼ぶことで、このサイトを閉じています。
なお、Web Intents のエミュレーションライブラリでは、データの受け渡しにpostMessage()を用いているのですが、即座にwindow.closeを呼んでしまうと、postMessageの処理が完了しないうちにwindowが閉じてしまい、データを戻せないため、500msec待った後、closeする処理を行っています。
このようにpostResult()で、データが返されると、呼び出し側では startActivityの第二引数で指定された callback 関数が呼び出され
function(data) {
$("#urlshortner .out").text(data);
}
画面に短縮後URLが表示されます。

ここで、さらに以下のURLにアクセスします。

上のページは、Web Intentsのデモサイトとなっており、やはり短縮URLを示す Intent タグが記述されています。
<intent action="http://webintents.org/shorten" type="text/uri-list" href="shorten.html" icon="favicon.ico" disposition="inline" />これにより、action = "http://webintents.org/shorten", type = "text/uri-list" に対して、新たに http://demos.webintents.org/shorten.htmlがWeb Intent として登録されました。
この状態で、もう一度先程のデモサイト(http://webintents.cloudfoundry.com/)にアクセスし、"shorten"のボタンをクリックしてみましょう。pickerには、新たに追加登録したWebアプリが表示されます。

さて、新たに登録した Intent では disposition="inline" と記述されていました。このため、このリンクをクリックすると、ピッカーウィンドウ内にアプリが表示されます。
ここで、"return" ボタンをクリックすると、呼び出し元のサイトに短縮URLが返されます。

今度は、きちんとした短縮URLですね :)
このように Web Intents を使うことで、その時々の好みに応じて、好きな短縮URLサービスを利用することが出来るようになります。他にも、画像編集サイトやURLの共有サイトなどを、ユーザーが自由に選択できるようになるなど、ユーザー中心型のWebアプリケーション連携が実現できます。
まとめ
今回は、Web Intentsの基本的な考え方や使い方を紹介しました。Web Intentsを使うことで、ユーザー中心型のWebアプリケーション連携を実現し、Android インテントのように、不足機能に対し、他のWebアプリの機能を利用することで、スピーディーなWebサイトの開発が可能となることがお分かりいただけたかと思います。
ただし、現在、WebIntentsの仕様は盛んに議論されている最中ですので、今回紹介した仕様は変更になる可能性が高いことにご注意ください。
さて、Web Intentsは、Device 機能の利用や、マルチデバイス連携サービスを実現するための重要なAPIとして、現在W3Cで検討が進められています。次回は、この点の詳細について紹介したいと思います。
Useful Links about Web Intents
- Web Intents Home Page
- Web Intents API spec (chromium project)
- Web Intents Wiki(W3C)
- 今回作成したサンプルコード(github)