OpenSocialを利用してガジェットを作ろう!

第5回アプリデータによる情報の永続化と共有

OpenSocial v0.9仕様策定が完了しました

かなり長い時間がかかっていたOpenSocialの次期バージョンであるv0.9の仕様策定作業が、先月の4月16日に完了したことが、OpenSocial Communityより発表されました。v0.9により、ガジェットの開発が今までよりも容易になるだけでなく、パフォーマンスの面でも改善されています。特に、Lightweight JavaScript APIや、OSML & OpenSocial Templatesなどを使うことで、今まで数十行の記述が必要だった箇所が、たった2、3行の記述で同じことを実現できるようになります。ガジェット開発者にとって、v0.9は非常に魅力的な内容となっています。

しかし、OpenSocialガジェット開発者がv0.9を利用するためには、OpenSocialに対応した各SNSがv0.9対応の実装を追加しなければならないため、しばらく待つ必要がありそうです。OrkutによるAlbum APIの一部対応など、v0.9を先取りしたSNSもいくつか登場しています。v0.9に興味のある方は、各SNSの動向をウォッチしておくと良いでしょう。

今回のテーマは「アプリデータ」

さて、第3回第4回の2回分を使って、DataRequestオブジェクトを使ったOpenSocial APIの使い方を見てきました。その中で、はてなIDを扱う箇所がありました。はてブチェッカーガジェットでは、自分のはてなIDの他にも、友達のはてなIDも扱うことが必要になります。

どのガジェットでも、ちょっと凝ったことをしたい場合に、ある情報をどこかに記憶しておきたくなります。はてブチェッカーガジェットの場合、このガジェットを使うユーザのはてなIDが、それにあたります。ガジェットを利用するたびにはてなIDの入力を迫られるのは不便ですので、ユーザに入力してもらったはてなIDは、はてブチェッカーガジェットの次回利用時にそれを入力することなくガジェットが利用できるように記憶しておきたい情報となります。

OpenSocialで提供される2つの記憶方法

普通のアプリケーションであれば、ファイルやデータベースなどを使うことで、こういった情報を記憶させておき、あとで再度利用することができます。OpenSocialによるガジェットでは、2つの選択肢があります。

  • ユーザ設定を使う
    • UserPrefタグとgadgets.Prefsクラスを使用
    • 設定値はガジェットのOwnerによって入力、記憶される
    • Owner以外のユーザは設定値を入手できない
  • アプリデータを使う
    • Persistence APIを使用
    • 設定値はガジェットのViewerによって入力、記憶される
    • 他のユーザの設定値を入手可能

ユーザ設定は、あるガジェットをインストールしたユーザが、そのガジェットの動作をカスタマイズするために使用される機構です。ガジェットXMLファイルにUserPrefタグを使ってユーザ設定項目を記述しておくことにより、gooホームSandboxでは自動的に設定値の入力画面を作ってくれます。入力画面で入力された設定値は、gadgets.Prefsクラスを通じてガジェット内で取得し処理することができます。

しかし、ユーザ設定項目は、あくまでOwner固有の設定値であり、ガジェットの実行時に他のユーザの設定値を入手することはできません。つまり、情報の記憶はできても、その情報を他のユーザと共有する目的で使えるものではないということです。

はてブチェッカーガジェットが扱うはてなIDの記憶については、アプリデータが適しています。ユーザ設定のように入力画面を自動的に作ってくれるような機構はありませんが、Viewerがガジェットの実行時に入力した設定値は、他のユーザがそのガジェットを使った際に、取り出すことができます。つまり、設定値の共有が可能ということです。同じガジェットをインストールしているユーザ間であれば、他のユーザの設定値をPersistence APIによって取得することが許可されています。

ユーザ設定とアプリデータでは、このように実現できることに差があります。扱いたい情報によって、どちらを使うか判断することが開発者に求められます。

Persistence APIと、はてブチェッカーガジェットでの利用箇所

では、具体的にアプリデータを扱うためのAPIとその利用箇所について見ていきましょう。アプリデータに関する操作は「作成(更新含む⁠⁠、削除、取得」の3つであり、それぞれAPIが提供されています。各APIはDataRequestの形式で提供されていますので、第3回第4回で解説したバッチリクエストの形態で利用することになります。

  • 作成:opensocial.DataRequest.newUpdatePersonAppDataRequest
  • 削除:opensocial.DataRequest.newRemovePersonAppDataRequest
  • 取得:opensocial.DataRequest.newFetchPersonAppDataRequest

はてブチェッカーガジェットのHomeビューでは、はてなIDについて2つの機能がユーザに提供されます。1つ目は、Ownerが自分のはてなIDを設定するためのUIの提供です。ここでは、入力されたはてなIDを記憶するために、newUpdatePersonAppDataRequestが使われます。

2つ目は、Ownerの友達のはてブ一覧を表示します。そのために、Ownerの友達のはてなIDを取得することが必要です。はてなIDの取得には、newFetchPersonAppDataRequestが使われます。

一方、Profileビューでは、プロフィールページをOwner自身のはてブ一覧で飾ることになります。そのために、Homeビューと同じく、newFetchPersonAppDataRequestが使われます。

アプリデータの作成、更新

Homeビューにて入力されたはてなIDは、newUpdatePersonAppDataRequestを使って、アプリデータとして作成、更新されます。リスト1は、入力されたはてなIDをアプリデータとして作成、更新するコードです。

リスト1 アプリデータの作成、更新
var id = $('#hatena_id').val();
var req = opensocial.newDataRequest();
req.add(req.newUpdatePersonAppDataRequest(
    opensocial.IdSpec.PersonId.VIEWER, 'id', id), 'self');
req.send();

jquery の$()関数を使って、hatena_idフィールドに入力された文字列を取得しています。その後、newUpdatePersonAppDataRequestを使って、アプリデータを作成および更新するためのリクエストオブジェクトを生成しています。その際に、以下の引数を指定します。

  • 作成や更新の対象とするユーザ
  • アプリデータのキー文字列
  • アプリデータの値とする文字列

gooホームSandboxだけでなく、ほとんどのSNSでは、newUpdatePersonAppDataRequestの第1引数としてViewerの指定のみ許可しています。これは、他のユーザのアプリデータを勝手に更新されてしまうことを防ぐための制限です。

作成や更新するアプリデータの指定方法から見てわかる通り、アプリデータはKey-Value型のデータベースです。ガジェットごとにこのようなKey-Value型データベースを利用することができることは、ガジェット開発者への負担(外部にデータベースを設置する、データベースを設計する、など)を大きく軽減させることでしょう。リスト1では、'id'という名前をキー名として、入力されたはてなID文字列を値としてそれぞれ指定しています。他にもアプリデータとして記憶したいものがあれば、個別にnewUpdatePersonAppDataRequestを使ってリクエストオブジェクトを生成します。

あとはリクエストオブジェクトをDataRequestオブジェクトにadd()関数を使って追加し、send()関数を呼び出してサーバに送信します。もし既に'id'というキーの値が記憶されていた場合は、新しい値で更新されます。

アプリデータの取得

次に、記憶されているアプリデータの値を取得するための手順について紹介しましょう。アプリデータの取得には、newFetchPersonAppDataRequestを使用します。この際に必要となることとして、⁠誰のアプリデータを取得するか」ということがあげられます。

第3回で、⁠どのユーザの情報を取得するか?」という条件を表すために、IdSpecオブジェクトを使うことを紹介しました。IdSpecでは、次の2つを指定してユーザの集合を表現することが可能です。

  • 基準となるユーザ(ユーザID)
  • そのユーザと他のユーザの関係(グループID)

newFetchPersonAppDataRequestによるアプリデータの取得に関しても、このIdSpecオブジェクトが使用されます。

まずは、Ownerが持つアプリデータの取得を見ていきましょう。リスト2をご覧ください。

リスト2 Ownerが持つはてなIDの取得リクエストの生成
var req = opensocial.newDataRequest();
var myself_params = {};
myself_params[opensocial.IdSpec.Field.USER_ID] =
opensocial.IdSpec.PersonId.OWNER;
myself_params[opensocial.IdSpec.Field.GROUP_ID] =
opensocial.IdSpec.GroupId.SELF;
var myself = opensocial.newIdSpec(myself_params);
req.add(req.newFetchPersonAppDataRequest(myself, 'id), 'selfAppdata');

myself_params オブジェクトに、USER_IDをOWNERに、GROUP_IDをSELFとして指定することで、OWNER自身を示すIdSpecオブジェクトを生成しています。そしてこのIdSpecを使って、newFetchPersonAppDataRequetにより、Ownerが持つ'id'というキーの値を取得するリクエストオブジェクトを生成します。

次に、リスト3をご覧ください。

リスト3 Ownerのアプリデータの取得
req.send(function(response) {
  var myself = response.get('selfAppdata').getData();
  for (var id in myself) {
    var hatena_id = myself[id].id;
    // do something...
  }
});

結果のコールバック関数の引数には、要求したアプリデータが格納されています。まずは、'selfAppdata'というリクエストオブジェクトの追加時に指定した文字列を使って、get()関数によりResponseItemオブジェクトを取得して、さらにgetData()関数によりアプリデータが格納されたオブジェクトを取得します。そのオブジェクトは、リクエストオブジェクトの生成時に指定したIdSpecオブジェクトの条件に一致するユーザのIDをキーとする配列です。リスト2とリスト3の場合は、Ownerの一人だけを指定していますので、for文は1回のみループし、idはOwnerのIDとなります。

IdSpecオブジェクトによる条件指定が複数のユーザを示す場合は、リスト3のfor文はそのユーザ数だけループすることになります。リスト4は、Ownerの友達のアプリデータを得るためのコードです。

リスト4 Ownerの友達が持つはてなIDの取得
var req = opensocial.newDataRequest();
var owner_friends_params = {};
owner_friends_params[opensocial.IdSpec.Field.USER_ID] = 
opensocial.IdSpec.PersonId.OWNER;
owner_friends_params[opensocial.IdSpec.Field.GROUP_ID] =
opensocial.IdSpec.GroupId.FRIENDS;
var owner_friends = opensocial.newIdSpec(owner_friends_params);
req.add(req.newFetchPersonAppDataRequest(owner_friends, 'id), 'ownerFriendsAppdata');

req.send(function(response) {
  var owner_friends = response.get('ownerFriendsAppdata').getData();
  for (var id in owner_friends) {
    var friend_hatena_id = owner_friends[id].id;
    // do something...
  }
});

リスト4の内容は、はてブチェッカーガジェットのHomeビューにて、友達のはてブ一覧を取得するために使われています。

まとめ

今回は、アプリデータによる情報の永続化と、他のユーザのアプリデータを取得するための手順について紹介しました。アプリデータは多くのガジェットにおいて使われる頻度が高い機構ですので、ぜひ自分のものにしておいてください。

はてブチェッカーガジェットは、はてなブックマークサービスからコンテンツを得て表示することが中心的な機能となります。次回は、makeRequestによる外部サービスの呼び出しについて解説を行う予定です。お楽しみに!

おすすめ記事

記事・ニュース一覧