School is the opposite of fair...riaf

seen from United Kingdom

seen from Germany

seen from Egypt
seen from United States
seen from United States
seen from Türkiye

seen from Egypt

seen from Egypt
seen from Germany
seen from China
seen from Singapore

seen from India

seen from United States
seen from Vietnam

seen from Netherlands

seen from Singapore
seen from South Korea
seen from Netherlands
seen from China
seen from South Korea
School is the opposite of fair...riaf
jquery-tutor というプラグインを作りました
おひさしぶりです。riaf です!
今日は、ちょっとした jQuery Plugin を作ってみたのでその紹介です。 ちなみに、まだ Crocos のサービスには使用していないので、ちゃんといろんな環境で動くかどうかはわかりません..。 おかしなところがあったらぜひぜひ Pull Request をおねがいしますね!(見た目をかっこ良くしてくれたりとかも大歓迎です!)
何をするプラグインか
サンプル を見ていただければイッパツなんですが、 ウェブサービスのチュートリアルを、そのサイトを実際に見ながら進めるやつ、あるじゃないですか。
あれがそこそこ汎用的になってるとやりやすいなーと思って作ってみました。 Crocos には Hack Hour という制度があり、先週末の Hack Hour で気分が高まって作ってみた、というレベルの状態ですので、今後ちゃんとプロダクション環境で使えるようにして行きたいと考えています!Hack Hour については、後ほど紹介します。
使い方
jquery-tutor.min.js を読み込んだら
$(function() { $.tutor({ steps: [ { target: '.step-one', message: 'まずは、ここから' }, { target: '.step-two', message: '次は、ここ。' } ] }); });
のようにして、操作の対象になる element を target に指定して、表示するメッセージを設定します。 Next ボタンを押したら次のステップに移動します。
steps に指定できるのは element を指定した object だけではなく、何かする function を指定することもできます。 Deferred Object を return すると、resolve されるまで次のステップは実行されません。
$(function() { $.tutor({ steps: [ function() { alert('Welcome!'); }, function(dfd) { // async FB.api('/me', function(me) { alert(me.name + 'さんですねー!'); dfd.resolve(); }); return dfd.promise(); } ] }); });
ダウンロードなど
GitHub で公開しておりますので、煮るなり焼くなり...!
crocos/jquery-tutor · GitHub
https://github.com/crocos/jquery-tutor
Hack Hour について
毎週金曜日の 2 時間、仕事とは関係がない(もちろん、関係があっても OK。というか、技術的なことならだいたい関係してきますよね)技術の勉強とか、開発とか(たとえば、社内で使っている wiki システムの新機能開発とか)をする時間が設けられています。 わりと最近はみんな忙しくて参加率低めなんですが、ゆるゆると「今日はこんなことやろうかな!」と宣言して終わる頃に「ここまでやったよ!」みたいな共有をして終わります。
この Hack Hour で仕込んでいるネタもいろいろあるので、今後もブログとかで報告していけるといいなーと思ってます。
Titanium と alloy ではじめるスマートフォンアプリ開発
連日のブログ更新に触発されて今日も書いちゃいます、Crocos の人柱担当、佐藤 (@riaf) です。
というわけで、本日は iPhone アプリとか Android アプリとかを JavaScript で開発できちゃうっていうステキなプロダクト Titanium Mobile のお話です。Crocos ブログのくせに、 Facebook の話題はまったくありません!
いずれは Facebook と連携するアプリの開発方法とかをご紹介できればとおもいますが、まずはまだあまり日本語の情報がない alloy についてのご紹介です!
alloy とは?
Titanium Mobile の開発元である appcelerator が GitHub で公開している、Titanium 向けの MVC フレームワークです。
この記事を書いている 2012年 7月現在は、Unstable バージョン(日本語にすると一般的には不安定バージョンとでも言うんでしょうか)の状態ですので、Stable リリースの頃にはまた違うものになっているかもしれませんが、人柱担当としては手を出しておくべきかと思いまして、alloy を使って iPhone アプリを作ってみようと思います。
https://github.com/appcelerator/alloy
アプリ開発を始める
alloy は Titanium 向けのフレームワークですので、まずは Titanium SDK が必要になります。
今回は Mac で開発をしたので、Titanium Studio の Mac 版をダウンロードしました。
早速起動してプロジェクトを作ってみます。iOS アプリを作るときは iOS の SDK が、Android アプリを作るときは Android の SDK のセットアップが必要です。このへんは巷に導入方法がたくさんありますので、そちらにお任せして、今回は crocos というアプリを作成してみました。
割と適当にこんなかんじに作成してみました。そうすると、最低限なコードが作られています。
$ ls CHANGELOG.txt LICENSE LICENSE.txt README Resources build manifest tiapp.xml
これで、Titanium の準備は完了です。
alloy をインストールする
alloy は npm で配布されているので、node を動作させる環境を作っておくと良いでしょう。僕は、nodebrewというツールで node や npm を管理しています。とても便利なので、オススメです!
さて、alloy のインストールは
npm -g install alloy
とするだけです。これで、 alloy コマンドが使えるようになります。
$ which alloy /Users/riaf/.nodebrew/current/bin/alloy
alloy をセットアップする
それでは、先ほど作成した Titanium プロジェクトのディレクトリに移動し、alloy をセットアップします。
# もちろん、環境によって読み替えて下さい。 $ cd ~/Documents/Titanium_Studio_Workspace/crocos $ alloy new .
alloy のセットアップは alloy new するだけです。
# 上の続きです $ alloy new . .__ .__ _____ | | | | ____ ___.__. \__ \ | | | | / _ < | | / __ \| |_| |_( <_> )___ | (____ /____/____/\____// ____| \/ \/ Alloy by Appcelerator. The MVC app framework for Titanium. 2012-07-11 23:44:20 -- [DEBUG] Creating directory: plugins 2012-07-11 23:44:20 -- [DEBUG] Creating directory: plugins/ti.alloy 2012-07-11 23:44:20 -- [INFO ] Deployed ti.alloy plugin to plugins/ti.alloy/plugin.py 2012-07-11 23:44:20 -- [INFO ] Installed 'ti.alloy' plugin to tiapp.xml 2012-07-11 23:44:20 -- [INFO ] Generated new project at: app
Generate できました。
ここで、とりあえず iOS シミュレーターで実行させてみようと思います。が、nodebrew 等を使っている環境でそのまま実行 (Mac の場合は F11 にショートカットがあるようです)しようとすると、OSError: [Errno 2] No such file or directory と言われてしまって、実行することができません。
これは、plugins/ti.alloy/plugin.py に記述されている node や alloy のパスが /usr/local/bin で決め打ちされてしまっているためなので、対象の行を修正する必要があります。
具体的には以下のように書かれているところを、実際に node や alloy が存在するパスに書き換えてやります。 (現在は 27 行目付近)
cmd = ["/usr/local/bin/node","/usr/local/bin/alloy", "compile", f, "--no-colors", "--config", cfg]
修正した後にもう一度ビルドすると、以下の様な画面を見ることができます。テキストをクリック(タップ)すると、アラートが表示されるだけのサンプルです。
alloy のディレクトリ構成
alloy では、基本的に app ディレクトリの中を編集します。
主に以下のファイルを読むと構造がわかると思います。
app/controllers/index.js
コントローラ。テキストがクリックされたときにアラートを発生させるコードが書かれています。
$.t.on('click',function(e) { alert($.t.text); }); $.index.open();
app/styles/index.json
スタイル。CSS のように、見た目に関するデータ(色や、サイズなど)が書かれています。
{ ".container": { "backgroundColor":"white" }, "Label": { "width": Ti.UI.SIZE, "height": Ti.UI.SIZE, "color": "#000" } }
app/views/index.xml
ビュー。HTML のように、実際に配置する要素が書かれています。
<Window class="container"> <Label id="t">Hello, World</Label> </Window>
このサンプルではモデルは使われていないので、MVC の分離という意味では物足りないかもしれませんが、このように、 alloy ではウェブアプリケーションを開発したことがある人には馴染みのあるようなファイル構成で、スマートフォンアプリを開発することが出来るようになります。
とはいえ、まだまだ開発中っぽくて、どんどんコミットされているプロジェクトですので、業務での活用は難しいかもしれませんが、今後はこういった流れもあるかもと思っていると、心の余裕ができて良いですよね!
ぼくは、まず休日にでも、お遊びでアプリ開発してみようと思います!進捗があったらまたブログに書こうと思いますのでお楽しみに...!(Facebook 連携まで進めるだろうか...)
crocos-js を GitHub で公開しました
みなさんこんにちは!御無沙汰しております!
@riaf、またの名を佐藤と言います!
社内ライブラリを OSS 化するとモテると聞いた(誤解)ので、そのご紹介です!
Crocos 社内で使用している JavaScript ライブラリを GitHub で公開しました。
https://github.com/crocos/crocos-js
以前は CoffeeScript で開発していたため、その名残りが少し残っています。
一部、汎用的ではない部分を除いています。Crocos 社内用のライブラリは、今回公開したコードに一部機能を追加して build しています。
本日は、このライブラリの簡単な使い方とかを紹介します。 crocos-js で出来ることはざっくりと以下のようなものです。
ライブラリの読み込み待ち
キャッシュ機能 (localStorage ベース)
xfbml の拡張機能 (fbx)
[for CSS] ログイン状態の判定
[for CSS] iframe 内かどうかの判定 (Facebook の Canvas ではありがちなやつ)
雑多な奴 (nl2br、truncate、redirect)
全てカバーできてませんが qunit を使ったテストもあります。こちらもサンプルとして参考になるかもしれません。
https://github.com/crocos/crocos-js/tree/master/test/unit
簡単な例を挙げながら以下、使い方です。
読み込む
どの機能を使うにもとりあえず html で読み込まなきゃ行けないのですが、jQuery に依存しているので、jQuery の後に読み込んでください。
たとえば:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script> <script src="crocos.min.js"></script>
xfbml の拡張 (fbx) を使う
Graph API にリクエストした結果を自動的に HTML に展開する機能があります。
<span class="fbx-graph" data-fbx-id="1276368138" data-fbx-field="name"></span>さん、ようこそ!
これだけだと xfbml でも出来るんですが、 xfbml だとあまり大量のタグを利用できなかったり、他のプロパティが使いたい時があったりするのでこの機能を追加してあります。
class に fbx-graph が指定されているタグは Graph API リクエストを行うタグです。data-fbx-id にオブジェクトの ID を、data-fbx-field には表示したい要素名 (name とか email とか picture とかの文字列) を指定します。
また、URL に対する Like の数を表示したい場合に使える fbx-like-count もあります。
♥ <span class="fbx-like-count" data-fbx-url="http://crocos.co.jp"></span>
キャッシュ機能
まだテスト中ですが、localStorage を利用したキャッシュ機能も実装してあります。 localStorage が無いと動作しないので、今は beta 扱いです。
crocos.cache.set、crocos.cache.get、crocos.cache.hasの他に crocos.cache.with というメソッドがあり、以下のようにキャッシュがある場合とない場合を並べて書けるので便利です。
// `cache_key` という名前でキャッシュを探す crocos.cache.with('cache_key', function(dfd) { // キャッシュがない場合の処理 FB.api('/me', function(response) { dfd.resolve(response); }); return dfd.promise(); }, { expire: 3600 }).done(function(response){ // キャッシュがあっても無くてもここで受け取れる console.log(response); });
自動的に html に class をつけます
iframe 内で表示されるものと、外部の URL で表示するものを同じリソースで管理したいことがありました。 crocos-js では、<html>に iframe 内の場合は in-frame、外の場合は self-frame というクラスを付与します。あとは CSS で .in-frame .anyelements { .. } のように記述するだけで、iframe 内の時だけ指定したいスタイルなどが適用できます。
また、Facebook のコネクト状態によって fbstatus-connected のようなクラスも付与します。fbstatus- の後に FB.getLoginStatus(function(response){}) したときの response.status を結合した文字列になります。
Facebook JS SDK の読み込み待ちをする
Facebook アプリを開発していると、FB.initされたかどうか分かんないタイミングがあったりとか、共通化したいところで「そもそもこのタイミングで FB がある保証なくね?」とか悩むことがあったので、変数が存在するかどうかを判定して、定義されたら実行する関数を登録できるようにしてあります。
Facebook のみ、FB.init されているかどうかを判定したいので、FB.initを記述する際に window.crocos_facebook_initialized = true; と書く必要があります。
つまり、以下の様にします。
window.fbAsyncInit = function() { FB.init({...}); // Additional initialization code here window.crocos_facebook_initialized = true; }
そうすると、あとは crocos さえ定義されていれば以下のように記述できます。
crocos.wait("FB").done(function(){ // ここでは FB 初期化済み FB.api("/Crocos.Inc", function(response){ console.log(response); }); });
以上、ざっくりと解説でした。 まだまだ追加したい機能があるので、これからも開発続けていきます!
ただ、開発者は僕一人で、そもそもゆるふわ PHP プログラマなので、いろいろとアレなところがありそうですが、ぜひぜひツッコミとか Pull Request とかお待ちしておりますので、よろしくおねがいします!
意外と知られていない、Facebook API の使い方
連続でこんにちは、Facebook で飲みに行く人を募っても「いいね!」しか付きません...。@riaf(Facebook) です...。
Facebook アプリを開発するときに必ず使うことになる Facebook API ですが、普通に使っているとなかなか気づかないような使い方があったりします。 今回は社内の情報共有のために使っている wiki にメモしておいたものから、意外と知られていない API の使い方を幾つか紹介しようと思います。
API のパラメータに locale をセットできる
アプリを開発するうえできっとすぐに当たる問題「ユーザー名を日本語で取得したい」という悩みがあるかなと思います。 いろんな条件で API を実行してみて「どうやら FQL の profile テーブルからなら取れるっぽい?」とか「access_token が付いているとダメっぽい?」とかやってみるものの、いまいち正解がわからないやつです。(わりと共感していただける方も居るのではないでしょーか)
実はこれ、API リクエストのパラメータに locale をセットするだけなんですね。 以下に、PHP で英語の名前と日本語の名前を取得する例を示します。
<?php $path = '/1276368138'; $response = $facebook->api($path, ['locale' => 'en_US']); echo $response['name'], PHP_EOL; // => "Keisuke Sato" $response = $facebook->api($path, ['locale' => 'ja']); echo $response['name'], PHP_EOL; // => "佐藤 佳祐"
と、このように言語を指定して情報を取得することが可能です。
デフォルトだと返ってこない値も取得できる
たとえば「友だちリストと一緒に友達の誕生日情報も取得したい。」みたいなことってたまにあるんですよね。で、まじめにドキュメントに書いてある通りにやろうとするときっと「FQL の multiquery で友だちリスト取得して、それを WHERE IN に入れて、各ユーザーの詳細情報を取得する」という方法が思いつきますが、FQL を複数リクエストすると、レスポンスが遅いし結果を結合したりするのが面倒だったりします。 これも、ちょっとパラメータに工夫をするだけで情報を取得できます。以下にサンプルを示します。
<?php $response = $facebook->api('/me/friends', [ 'fields' => 'id,name,birthday', 'limit' => 5, 'locale' => 'ja', ]);
通常、/me/friends にリクエストすると id,name だけが返ってきますが、このように fields に id,name,birthday を指定すると、その値がそのまま返ってきます。 (もちろん、friends_birthday といったパーミッションが必要です)
Page Access Token を /me/accounts 以外の方法で取得
Facebook ページの管理権限を利用するアプリ (manage_pagesを要求するやつ) だと、ページに対するアクセスは Page Access Token を使えという事になっています。 前回の記事では /me/accounts でページ一覧とアクセストークンを一緒に取得していましたが、特定のページのアクセストークンだけが欲しい場合はこれでは無駄ですし、面倒です。 これも、先の fields パラメータを使うと以下のように記述できます。
<?php $response = $facebook->api('/174849262641057', [ 'fields' => 'access_token', ]);
manage_pages が有効なアクセストークン付きで /PAGE_ID?fields=access_token にリクエストすると Page Access Token が取得できます。
ちょっとマニアックなネタでしたが、今日はこのへんで!次回以降も、たまにこういうネタも書きたい気持ちです。
ちなみに今日は Facebook Night vol.6 に参加しようと思っていますので、参加される方はよろしくおねがいします!
JavaScript で Facebook アプリを作って Heroku に置いたお話
はじめまして! @riaf (Facebook) です。クロコスでは PHP も書いていますが、最近はわりと JavaScript を書いていることも多いです。
趣味は、Facebook API を追いかけることです。
先日、ふと思いついたアプリを作ってみたお話を書いてみます。
今回作ったアプリは こちらから実際に使用できます。
前回までのあらすじ
Facebook ページの管理者が一喜一憂した「タイムライン化」。
そのタイムライン化により追加された新機能「メッセージ」であったが、同時に複数ページを管理しているとそれぞれのメッセージに気づきにくいという問題も引き起こしていた。
解決の光
ちょっとつかれたので普通に書きますが、
こういったちょっとした問題の解決にも Facebook アプリは有効です。 今回の場合、「管理しているすべてのページのメッセージを新しい順に表示するだけのアプリ」を作ってあげれば、巡回の手間が省けるのではないかと考えました。
Facebook API を調べてみる
まずは「そもそも、ページに対するメッセージを取得できる API が存在するか?」を見てみます。
ページに属しているメッセージなので、Graph API の Page オブジェクトの あたりを調べると分かりそうです。
実際に見てみると、Messages という項目があり、どうやらページに対するメッセージは取得できるようです。
しかし、ドキュメントには次のように記述されています。
You can read the messages for a page by issuing an HTTP GET request to /PAGE_ID/conversations with a Page Access Token and read_mailbox permission.
つまり、/PAGE_ID/conversations に対して read_mailbox の権限を持った Page Access Token が必要になるということです。
試しに何も権限を持っていない状態で API にアクセスすると、当然ですが (#298) Requires extended permission: read_mailbox という OAuthException が発生します。
このペースで書いていて、果たして Heroku に置くところまでたどり着けるか不安になって来ました。
アプリを実装してみる
とりあえず実装を始めてみることにします。
今回は、ちょっと backbone.js について造詣を深めたいと思ったので、すべて JavaScript で実装してみることにしました。
何はともあれ、まずは新規アプリケーションを作成します。JavaScript だけで実装するつもりなので、ここで必要なのは appId のみです。ドメインなどの設定だけきっちりしておけばとりあえずは動くかと思います。
実際のアプリの HTML ソースを表示するとおわかり頂けるとおもいますが、HTML 自体は 100 行に満たない程度です。
実装に関しては外部 JavaScript ファイルに記述してあります。 // Generated by CoffeeScript 1.3.1 というコメントのとおり、実際は CoffeeScript で開発しました。shadow.vimを使っていて、僕はとても面倒くさがりなので実際の CoffeeScript のソースコードも app.js.shd からアクセス出来るようになっています(ひどい)。
ソースコード上では、アクセスしている人の permission のチェック (read_mailbox があるか?) や、 FB.defer の拡張 なども行なっているのでちょっと面倒な部分もありますが、本質的には以下の処理を行なっているだけです。
/me/accounts から自分が管理している Facebook ページと、Page Access Token のリストを取得
取得したページに対して /PAGE_ID/conversations を取得
取得できた順に backbone.js の Model を生成して、Collection に追加、View を reflesh
ソースコード上では以下の部分です。
main = -> check_permission().done -> FB.defer.api("/me/accounts", { fields: "id,name,category,access_token,link" }).done (response) -> pages = [] for page in response.data if page.category != "Application" pages[pages.length] = page fetch_messages_by_pages pages .fail -> alert "permission error!" thread_view.render() fetch_messages_by_pages = (pages) -> for page in pages do (page) -> FB.defer.api("/#{ page.id }/conversations", { access_token: page.access_token }).done (response) -> if "data" of response for conversation in response.data thread = new Thread $.extend {}, conversation, { page: page } thread_view.add_thread thread
アプリを公開する
なんかすごく端折った気がしますが、、、
今回は Facebook アプリとして利用したかったので、SSL (https) が必要でした。最初は github pages を使おうと思っていたのですが..。
そこで、Facebook アプリ管理画面からもクリックするだけで SSL が有効なサーバーが用意される神サービス Heroku を使ってみようと思いました。
が、このアプリは特にサーバーサイドの実装は無く、ただ単純に静的ファイルをホスティングするだけだったので、どう考えても Heroku の出番ではないのですが、以下の様な js をデプロイし、サーバーは node.js で作成しました。
var connect = require('connect'); var port = process.env.PORT || 3000; var app = connect() .use(function (req, res, next) { // force req.method = 'GET'; next(); }) .use(connect.static('public', { maxAge: 3000000 })) .listen(port);
これは、、ひどい。
あとは通常の Heroku アプリのデプロイ (git push) をするだけでした。なんて楽チンなんでしょう...。本当に申し訳ない。
つまり
Facebook アプリって、このようにクライアントサイドの JavaScript だけでも作れちゃうものなんです!
なんかお手軽な感じがしてきますね!
最近はスパムアプリもたくさんあって、アプリを敬遠している方が増えていたり、プライバシー設定でアプリに渡す情報を制限したりとかしてしまう方向になっちゃいがちですが、アプリも使いようによっては、このように何かがちょっと便利になったり、問題を解決できたりする便利なツールにもなるので、行儀の良いアプリが増えて、みんなが楽しめる世の中になると良いなあと思っています。
という意味では、App Center には期待出来るかもしれませんねー!