飴屋

mixiアプリ/日記11

次第に整備されつつあるmixiアプリ

mixiアプリの枠組みの変化は、いまだ衰える様子がありません。ある意味、アプリが出揃ってきた感もあり、現状のカテゴリによる分類がユーザのニーズに必ずしもマッチしていなかったのか、カテゴライズに関する大きな修正が入るようです。これまで自己申告してきたカテゴリについても、mixi側の審査によって今後は振り分けられるようになるそうです。また、ユーザがアプリにたどり着くまでの導線についても今後手を加えられていくことになりそうです。「ランキング」順にソートされていた一覧画面の順番が一時期乱れたことがありましたが、大手のアプリにとってこれはかなりの露出が減るという結果を生んだようです。(私は大手のアプリを持っていないので、気になりませんでしたが。)こと露出という点では、初期の段階から人気を博しているアプリほど露出が増え、ユーザも人気のアプリがわかりやすいという構造ができあがっていましたが、これは逆に新しいアプリの露出が増やしにくいものでもあり、新しいアプリは少しの期間に「新着」順の一覧の最初のページにできる限りユーザを集めないとならないという状況を生んでいたとも考えられます。アプリのバラエティでユーザを獲得したいのであれば、この開発者のモチベーションが下がる構造を打破するのが得策のようにも思います。Facebookはずっと人気アプリのユーザ寡占状態にある、なんていう話を読んだことがありますが、メディアにも大きく取り上げられている今のうちに、mixiも何か手を打ってくるんじゃないかと期待しています。

あとはmixiが開発者に求めるアプリの品質というのも、徐々に敷居が上がっているように感じます。ユーザに一定以上の体験を与える価値があるアプリを選別していこうという気概がみられますね。あんまりネタアプリを排除しないで欲しいような気もしますが、ユーザにがっかりさせたくないという取り組みとしては、よろしいのではないでしょうか。自分の作っているアプリもできれば人に楽しんでもらえるものにしていきたいですしね。

どうもその品質保持の一環からか、アプリ自体の品質の他にも運営側にも一定限度の能力を要求し始めるようでもあります。外部サービス(課金とかAPIとか広告とか)の利用に関する制限も増えましたし、外のURLへのリンクの要件も厳しくなってそうです。アプリはあの画面の中で完結させるのが作法といえば作法ですから、その辺はあまり気にしていないのですが、サポート掲示板の在り方についての注文がいろいろ増えてきたようです。機能の強化もはかられながら、サポート掲示板は運用側がきっちり取りしきれってことらしく、トピックの作成権限の限定や、作ってはいけないトピックの類型なども挙がっていました。ここから不用意にマイミクを増やさせようとする流れを作るのはmixi側も望んではいないということが感じ取れて、ちょっと面白かったです。マイミク招待による特典っていう仕組みが本当にネックになるアプリもあるので、ユーザ間でアプリを誘いあってくれるのは開発者としてはすごくうれしいのですが、無意味な勧誘合戦を強いるようなことはしたくないなというのが私の本音でした。アプリ用のマイミクを募集するトピックは今後、淘汰されていく予定だそうです。

さらにそれと関連してなのか、開発者用のコミュニティにも名称変更とトピックの大幅な削除という措置が先月くらいに取られました。自分は、βテスターを募集するトピックでまさに募集をかけたばかりだったので、突然アプリの申請が途絶えて初めてこの事態に気がつきました。頻繁にコミュニティを覗いておかないと、何が起こるかわからないというのも怖いですね。

http://mixi.jp/view_appli.pl?id=11085

なお、上記URLのアプリは2010/2/24現在もβテスターを募集しています。興味のある方はチラッと覗いてみてください。じきに公開予定ではありますが、サーバの負荷がどの程度のものになるのかある程度検討をつけたいところです。

アプリに情報を記憶させる

今回はmixiの提供するデータベースに、アプリ内で生成されたデータを格納する方法について書いていきたいと思います。最初はあまりピンとこなかった機能ですが、最初の一歩としてアプリ内のユーザの獲得した特典の数値を記憶させてみたところ、いろんな応用が利きそうなことに気がつきました。今後活用していきたい機能でもあります。

データベースのことに詳しいわけではないのですが、KVSというタイプのデータベースが使えるらしく、「どのデータが欲しいか」という情報をキーにして、サーバに要求すると、値が返ってくるという仕組みになっています。このタイプのデータベースはRDBMSのように値同士に縦のつながりや横のつながりを持たせられないのですが、シンプルな分スケーラビリティに優れているとかなんとか。世の中にクラウドコンピューティングが浸透してくると、親和性の高いこんなデータベースを使うことも増えていくのかなと思っています。

opensocialでいうところのPersistence APIというのを利用するのでmixiのデベロッパーセンターでは「情報の永続化」という言葉でこの機能が説明されています。未来永劫情報が保存されてしまいそうな名称ですが、情報の更新も削除もできるので安心です。「アプリがデータベースサーバに影響を残す」みたいな意味だと思うのですが、persitenceの妙訳が思いつきません。

「どのデータが欲しいか」というのをキーに情報を取り出すという操作ですので、キーの指定の方法が大事になってくるわけですが、ソーシャルアプリにおいてもちろんキーは「人」になります。具体的には以下の情報を元にキーが作成されます。

  1. どのアプリか
  2. 誰を起点にどの範囲までの人か
  3. 値の名前

「どのアプリか」は開発者側で指定することはできません。なので、アプリAで作成した情報をアプリBで読み込むというようなことはできません。逆にいうと自分のアプリは他のアプリの影響を一切受けないので、アプリの個別性が確保されます。

「誰を起点にどの範囲までの人か」という指定は、既にマイミクの情報を取得するときに体験済みですね。起点になるのはVIEWER(アプリを見ているユーザ当人)のみです。そして、VIEWERのマイミクまでの範囲を指定して情報を取得できるそうです。この機能を使って点数のランキング機能を作った場合、マイミクが同じアプリを使ってないと一人ぼっちの寂しいランキング表になってしまい、ちょっと寂しいので、「マイミクのマイミク」ぐらいまで範囲を広げられればいいのにな、なんて思うこともありますが、「共通のマイミクを持つ人」との交流には特にmixiは力を入れていないように思えるので、この範囲について広がる可能性はなさそうですし、それがmixiの持ち味なのかもしれません。

「値の名前」というのは、情報に一意性を持たせるためのものですので、自由に指定できます。アプリ内の得点であれば「score」とか命名すればわかりやすそうです。アバターを作るアプリであれば「eye」「nose」「mouth」「hair」みたいな名前で顔の造形パラメータを保存できそうですね。

この仕組みは、要するに「マイミクのデータを取得する」を拡張するものと考えると理解しやすくなるかもしれませんね。「mixiネーム」「血液型」「出身地」「誕生日」・・・といったmixi固有のデータとは別に、アプリで独自にユーザの属性を創設できるというのがこの機能の肝であります。そして、永続化情報の取得プロセスは「マイミクのデータを取得する」プロセスと非常に似通っているので扱いやすいのです。(呼び出しメソッドは「newFetchPeopleRequest」と「newFetchPersonAppDataRequest」と別ですが、引数は似たようなものです。)

情報の取得

// paramsで「誰を起点にどの範囲で」を指定
var params = {};
// VIEWERを起点に
params[opensocial.IdSpec.Field.USER_ID] = opensocial.IdSpec.PersonId.VIEWER;
// 範囲は「マイミク」まで
params[opensocial.IdSpec.Field.GROUP_ID] = "FRIENDS";
// idSpecが指定の実体オブジェクトになります
var idSpec = opensocial.newIdSpec(params);
var req = opensocial.newDataRequest();
// 「"comment"という名前」の値を取得します
req.add(req.newFetchPersonAppDataRequest(idSpec, ["comment"]), "response");
req.send(function(data) {
// 取得したデータの取り出し方は、マイミクの情報と一緒
var response = data.get("response").getData();
for (var id in response) {
// idが取得した人のmixi ID、msgに"comment"という名前の値が入ります
var msg = response[id]["comment"];
// do something...
}
});

上記は、デベロッパーセンターのコードにコメントを入れたものです。
newFetchPersonAppDataRequestの第二引数に「値の名前」の配列を渡すことで、必要なデータを指定できますが、「"*"」という文字列(ワイルドカード)を指定すると、アプリで保存している全ての種類の情報を取得してくれるようです。先のアバターのアプリだとすれば、["eye","nose","mouth","hair"]と全部列挙しなくてもいいってことになります。

もう一歩進めて、マイミクの基本プロフィール情報と一緒に取得できるようなAPIがあってもよさそうな気がしますが、それは自分で実装しろってことですよね。余談ですが、何度も何度も同じ情報(マイミクのプロフィールや永続化情報)を繰り返し取得してmixiアプリのサーバに負荷をかけるのは不作法だと思い、一度取得した情報はブラウザにキャッシュとして持たせるようにしています。マイミクによって頻繁に更新される情報でもない限りは、情報は何度でも再利用できますし、一つこの仕組みを作っておくと、別の機能で似たようなことをしたいときや別のアプリで似たようなことをしたいときにとても便利ですね。自分は自分で使いやすいように実装してますが、きっと似たようなライブラリを作って公開されている方もいるんでしょうね。

情報の作成

// msgの中身を「comment」という名前をつけて永続化する例
var msg = "Oops! ><";
var req = opensocial.newDataRequest();
// VIEWRの"comment"属性としてmsgの中身を保存してくださいというメソッド
req.add(req.newUpdatePersonAppDataRequest(opensocial.IdSpec.PersonId.VIEWER, "comment", msg), "response");
req.send(function(data) {
if (data.hadError()) {
var msg = data.getErrorMessage();
// 通信時にエラーが発生した場合の処理
} else {
var response = data.get("response");
if (response.hadError()) {
var code = response.getErrorCode();
// 保存時にエラー発生した場合の処理
} else {
// 保存に成功した場合の処理
}
}
});

データの保存と上書きは同じ方法で実現されます。
「誰の」「なんていう名前のデータを」「どんな値で」保存するかを指定するだけです。

エラー処理についてもデベロッパーセンターのサンプルコードでは言及されていますが、自分は処理の失敗によって致命的なエラーがでるようなアプリをまだ作ったことがないので、エラー処理についてあまり深く考えたことがありません。データの整合性を保つ必要がある場合は、この辺をしっかりしないといけないのでしょうけども・・・
例えば、ユーザAからユーザBにアプリ内コインが100円移動するようなケースでは、ユーザAの「coin」データを100減算したものを保存し、ユーザBの「coin」データを100加算したものを保存することになりますが、片方の保存処理が失敗した場合は、本来であればもう片方の処理もなかったことにしてあげなくてはなりません。そんなトランザクション処理をさせるのはこのAPIでは結構大変だと思います。エラー処理中に一方の処理を巻き戻す処理を行ったけど、それが万が一失敗したら・・・。

そもそも、ブラウザ上で実行されるJavaScriptで、そんなクリティカルな処理を行うこと自体間違ってるのかもしれませんね。persistence APIはあくまでも個人の属性を記すだけに留めて、値の改竄が許容される部分で使っていくというこうになりそうです、現状では。

情報の削除

// VIEWERのcommentという名前の値を削除する例
var req = opensocial.newDataRequest();
req.add(req.newRemovePersonAppDataRequest(opensocial.IdSpec.PersonId.VIEWER, ["comment"]), "response");
req.send(function(data) {
var response = data.get("response").getData();
if (response.hadError()) {
var code = response.getErrorCode();
// エラー時の処理
}
});

データの削除もデータの追加と同じような感じで「誰の」「なんていう名前のデータを」削除するかを指定するだけです。データを消す必要が出てくるケースってあんまり思いつかないですけども。

日記一覧