TitaniumMobile用Twitterライブラリtm_twitter_api

sxchu_1087539_11462380_friends.jpg
TitaniumMobileでTwitterを扱うときに便利なtm_twitter_apiの新バージョンを公開しました。

mogya/tm_twitter_api – GitHub

  • Androidでも動くようになりました!
  • twitterのUIが変わって動かなくなっていたので、新しいUIで動くようにしました

いずれも他の方が書いたパッチを取り込んだものです。オープンソースって素晴らしいですね。


使い方

Ti.include("lib/twitter_api.js");
//initialization
Ti.App.twitterApi = new TwitterApi({
consumerKey:'YOUR CONSUMER KEY of twitter API',
consumerSecret:'YOUR SECRET of twitter API'
});
var twitterApi = Ti.App.twitterApi;
twitterApi.init();

こんな感じで初期化します。CONSUMER KEYとSECRETは、Twitterの開発者ページでアプリ登録したときにもらえるものです。
twitter_app_page.png

twitterApi.init(); を初めて呼び出したときは、ユーザーさんにOAuthのための画面が掲示されます。ユーザーさんがアカウント名とパスワードを入れると、TwitterがPINコードというのを返してきますが、これはtm_twitter_apiが勝手に読み込んで認証処理が終了します。
initがすんだら、twitterのAPIを呼び出すことができます。とりあえずつぶやいてみましょう。

//status update
twitterApi.statuses_update({
onSuccess: function(responce){},
onError: function(error){},
parameters:{status: 'yah! this is my first tweet from twitter_api.js! '}
});

 つぶやくときは、Twitterのstatuses/updateというAPIをつかうので、tm_twitter_apiでは、twitterApi.statuses_update関数を呼び出します。
うまくいったときはonSuccess、なにか問題が起きたときはonErrorのコードが呼び出されます。
つぶやきの内容など、APIに渡す引数はハッシュparametersにいれて渡します。
この構造は、全てのAPIに共通です。

//get tweets
twitterApi.statuses_home_timeline({
onSuccess: function(tweets){
for(var i=0;i<tweets.length;i++){
var tweet = tweets[i];
// now you can use tweet.user.name, tweet.text, etc..
}
},
});

つぶやきを取得するコードです。onSuccessでtweetsという引数が渡されてくるので、これをループで回すと、つぶやきを取得することができます。

AndroidはGaraxySしか試せてないので、タブレット端末とかだと変わった動きをするかもしれません。どんなことになったか教えていただけると嬉しいです。
もちろんパッチも歓迎です(笑)

Titaniumのインクルードパスを指定する方法私案

(2011-06-07 21:29:06追記)この記事で書かれている現象はTitanium Mobile SDK 1.7で修正されます。しかも、予測とは違う仕様になったので、この記事に書かれているサンプルコードは動かなくなります。詳しくはTi.includeの不具合が1.7で修正される模様 – もぎゃろぐを見てくださいませ。
(追記終わり)

 TitaniumMobileでとっても困っていることが一つあって、Ti.include(‘lib/a.js’) って書いた時、iPhoneだと Resources/lib/a.js を見に行ってくれるんだけど、Androidだと Resources/lib/lib/a.js を見に行ってしまう。

#2585 Include paths for iphone and android are not based on the same starting point – Titanium Mobile – appcelerator

 
かなり困る問題なのに1.6.0でも直らないそうで、みんな困った末にこんな黒魔術が発見されました。

以下のように指定するとどの場所にあるファイルでTi.includeしても確実にファイルをインクルードできる。
Ti.include(“../../../../../../../../../lib/bookmark.js”)
TitaniumのインクルードパスをResourcesからの相対パスで指定する方法 | ひげろぐ

sxc.hu.657889.jpg

さすがにこれはちょっと(汗) ひげろぐの人が考えた訳じゃないし、考えた人だって困った末に編み出したのだとは思いますが、なんか鼻から悪魔とか出てきそうでムズムズします。

いろいろ試した末にたどり着いた別案。

var path_lib = 'lib/';
if (Ti.Platform==null || Ti.Platform.osname=='android'){
path_lib = '';
}
Ti.include(path_lib+'a.js');

Ti.Platformを確認しているのは、Android環境でTi.Platform環境がnullになることがあるから。

Appcelerator Developer Center – continuous 1.5.0 on android … ti.Platform.name crash

黒魔術よりはすっきりすると思うのですが、将来的に不具合が修正されたり、Andoirod以外の環境が出てきた場合にはコードを修正しないといけなくなる可能性が高いので、これはこれで問題があります。なんかもっといい案があればぜひ教えてください。

OAuth認証してツイートしてタイムラインを取得できるiPhoneアプリを10分で

TwitterのOAuth認証してつぶやいてタイムラインを取得できるiPhoneアプリを10分で作るというのを、昨日のスマートフォン勉強会@関西#13で実演してきました。

真っ白な状態のアプリに、OAuth認証を導入して、TextAreaで自由につぶやけるようにして、タイムラインを取得して表示するところまでで9:21。
動画の下、360pの左にあるCCボタンを押すと、解説が出るようになります。

先日公開したoAuthAdapter修正版を取り込んだtm_twitter_apiというのを使っています。

あと、補完機能は、emacsとAuto Complete Modeに自作の辞書を組み合わせたもの。10分で作る動画の場合、タイプミスしてビルドエラーが出ると撮り直しなので、補完機能はとても便利ですね。

コード:gist: 802605 – 10min twitter client- GitHub
USteram録画:古川大輔(mogya)「10分で作るtwitterクライアント」 スマートフォン勉強会関西#13

(2011-02-04 追記)
emacs autocompleteの辞書は、k1LoW/emacs-titanium – GitHubにあります。自分は、これを元にgist: 810559 – emacs titanium dictionary- GitHubを作って使っていました。

Re^2: Twitter oAuth Implementation for Titanium Mobile

バグがあったので修正しました。
mogya/oauth-adapter – GitHub
.bbpBox{background:url(http://a1.twimg.com/a/1295051201/images/themes/theme13/bg.gif) #B2DFDA;padding:20px;}

@mogya While executing Timer, received script error. ‘Result of expression ‘URL’ [undefined] is not an object. at oauth.js (line 453)’でした!Sat Jan 15 12:55:06 via web


一番最初、アプリケーションを起動してoAuth認証を通した直後にAPIを呼び出すと(=僕のブログコード通りに書くとw)、上記エラーになる不具合を修正しました。

ただ、またもや互換性が保てなくて、oAuthAdapter.send()の戻り値を使うのが無理になりました。申し訳ない。
sendから戻ってきたからといってAPI呼び出しが完了して戻り値が入っていることは保証できないので、その代わりにonSuccessコールバックを利用してください。

初期化部分も含めたコード全体は、readmeで見ることができます。

How to start

  • 新しくプロジェクトを作る
  • Resources/libディレクトリを作って、oAuthAdapter.jsと、oauth.js,sha1.jsを入れる
  • readmeのコードをapp.jsにべったり上書きする
  • ‘YOUR CONSUMER SECRET’,’YOUR CONSUMER KEY’,部分を自分のキーに置き換える。SECRETが先であることに注意
  • Launchすると、oAuth認証が立ち上がり、その後勝手につぶやき、タイムラインをデバッグコンソールに出力します。

解説

 Davidの書いたoAuthAdapterには、sendを呼び出した時点でoAuth認証が完了していなかったら、呼出をいったん保留して、認証後に再呼び出ししてくれるという機能が付いています。
 上記エラーは、この再呼出部分のコードを修正するのを忘れていたことが原因だったので、これは修正しました。

 ところが、そういう非同期の呼び出しが起こる以上、関数の戻り値にAPIの戻り値が入っていることは保証できなくなりました。(というか、最初から保証できなかったのですけど、僕が気づいていませんでした。)

 あと、全然別件なのですけど、Davidの書いたoAuthAdapterでは、sendの引数にtitleとpSuccessMessageを渡して、API呼び出しが成功すると、かならずポップアップが出る仕様になっています。update_statusならともかく、タイムラインを更新したり、バックグラウンドでユーザー情報を取得したりする場合、この仕様はちょっとありえません。

 二つの問題をバッサリ片付けるアイデアとして、titleとpSuccessMessageの使用を廃止して、代わりにonSuccessコールバックを採用することにしました。onSuccessコールバック関数の中でダイアログを出せば、従来と同じ挙動をすることができます。

iPhoneアプリを作る10の方法

第2回関西アンカンファレンスでしゃべってきました。

.prezi-player { width: 550px; } .prezi-player-links { text-align: center; }

友達に頼む

  • 技術的詳細を知らなくても機能を実現することが出来る
  • 愛と勇気しかお友達のいない方には向かない
  • レベニューシェアという手もあるよ

プロに頼む

  • lancersオススメ。過去の履歴が残るので発注価格の参考になる
  • 普通に発注すると、バージョンアップのたびに開発費用がかかる点に注意

ObjectiveC

  • Appleが認める正式な開発言語
  • なんでもできるから、これで開発できる人はそうするのが一番
  • めんどくさすぎだろjk…

Flash

  • FlashCS5からiPhoneアプリを作ることができる
  • デザイナさんとかは、Flashから入れるのでわかりやすいかも
  • 一度Appleの規約改正でNGにされた。その後再改正されて、現在は通るらしい。
  • でも、正直いつまただめになるかと思うと不安で不安で・・・

HTML+CSS+JavaScript

jQTouch

  • iPhoneブラウザで見てもらう
  • 1ページに複数ページの内容を書くなど、ちょっと違うけどまだまだ普通のWEB開発の範疇
  • HTML+CSS+JavaScriptでできること(GPS,ローカルキャッシュなど)は当然できる
  • カメラとかファイルアクセスはできない
  • iPhoneぽいUIにすることができる
  • AppleStoreに登録することはできない

jQueryMobile

  • みんな大好きjQueryをつかって、iPhone/Android/SymbianなどのブラウザでUIを実現しよう
  • まだベータ版。今月あたりに正式リリース?
  • 理屈上は、JavaScriptすら動かない環境でも見られるサイトになるそうだけど、その割にjQueryをロードしないといけないとか、正直まだよくわからない
  • jQTouchに比べて、幅広い環境で動くらしい
  • JavaScriptなので、カメラとかファイルアクセス、AppStoreはNG。

SenchaTouch

  • iPhone/Android向けライブラリ
  • jQTouch以上にリッチなUIが実現できる
  • キャンバス描画ができるので、ソリティアみたいなゲームも登場している
  • HTMLとCSSもつかうけど、bodyタグ空っぽのところに、JavaScriptで部品を挿入していくプログラミングスタイル。デザイナさんには厳しいかも。
  • JavaScriptなので、カメラとかファイルアクセス、AppStore登録はできない

PhoneGap

  • WEBページをiPhoneアプリにしてくれる仕組み。WEBKitブラウザを使って表示する
  • カメラとかファイルアクセスのためのAPIも用意してくれる
  • UIはjQTouchと組み合わせるのが一般的だと思う
  • 当然、AppStore登録が可能

TitaniumMobile

  • mogyaイチオシ!
  • JavaScriptでプログラムを書くと、iPhoneとAndroidのプロジェクトに変換、ビルドしてアプリを作る
  • PhoneGapのようにWebKitでHTML,CSS,JavaScriptのページを使うことも可能
  • カメラやファイルアクセスのためのAPIも用意されていて使うことが可能
  • AppStore登録も可能
  • HTMLやCSSは出番が無くなって、完全にJavaScriptプログラミングの世界なので、デザイナさんとかは無理だと思う
    一応、PhoneGapみたいな使い方もできないことはない

あと、発表後のQAで、.NET FrameworkをつかってiPhoneアプリを作るMonoTouchというのもあるよ、と教えていただきました。
今軽く見た感じだと、TitaniumMobileよりもっとObjectiveCよりで、ObjectiveCの開発環境から言語がC#に置き換わった、という感じでしょうか。開発環境が有償なのが注意点になりそうですね。

(2011-01-15追記)動画が公開されました。

コンテキストを超えた値の共有[TitaniumMobile]

sxchu_308383_titanium.jpg

TitaniumMobileプログラミングの話。
Windowを生成する時、urlパラメータを使うと、そのWindowは副コンテキストに分割されて動くことになるので、親コンテキストの変数を参照することは出来ません。

Window – titanium-mobile-doc-ja – UIカタログ – Window – Project Hosting on Google blockquote

これを乗り越えるための対策は、上記ドキュメントに書いてあるのですけど、微妙にいろいろ罠があって、実験して分かったことまとめ。

例えば、親コンテキスト(win1)の変数hogeがあって、副コンテキスト(win2)でボタンを押したらhogeをインクリメントしたい、というような場合。

main.jpg
sub.jpg

まず、親コンテキストの変数を子コンテキストで参照するには、こういう風にする。

var hoge = 1;
win2.hoge = hoge;

すると、子コンテキスト側からは、

var win2    = Titanium.UI.currentWindow;
Ti.API.debug("hoge:"+win2.hoge);

みたいにして参照することが出来る。
ただし、変数はby value渡しになるので、副コンテキストで値を変更してもメインコンテキストのhogeには反映されません。
なので、

button1.addEventListener('click',function(e){
win2.hoge = win2.hoge+1;
label.text = 'hoge:'+ win2.hoge;
});

こういうふうに書いても、main側ではhogeの変更は全く無視されてしまいます。

メインコンテキストに値を反映したい時は、

function update_hoge(value){
hoge = value;
}

という具合にセッターを用意してあげて、副コンテキストの方から

win2.update_hoge( Titanium.UI.currentWindow.hoge + 1);

という具合にして呼び出してあげると、メインコンテキストで実行されるので、値を反映することが出来ます。

button1.addEventListener('click',function(e){
win2.update_hoge(win.hoge+1);
label.text = 'hoge:'+ win.hoge;
});

ただしここにはさらに罠があって。update_hogeを呼んだからといって、副コンテキストが見ているwin2.hogeが勝手にアップデートされたりはしません。
なので、上記コードも、ボタンをクリックしても副コンテキストのhogeの値はちっとも増えないように見える。実際には、メインコンテキスト側のhogeが増えているので、いったんウインドウを閉じて開けば反映されるのですけど。

副コンテキスト側に値を戻してあげるには、update_hogeで反映してあげるしかないみたい。

function update_hoge(value){
hoge = value;
win2.hoge = hoge;
}

という具合にして書き戻すようにするか、get_hoge();を作るのがよいみたい。

コンテキストというのがスレッドのことなのかなんなのかによっては、意図しない順番で処理が実行されたりしそうで怖いのですけど、その辺は明日えらい人たちに聞いて勉強してこようと思います。

おまけ

というわけで明日(あ、今日になっちゃった)は
はてな技術勉強会 Hackathonです。@masuidriveをはじめ、TitaniumMobile関係えらい人がいっぱい集まるのにもかかわらず、まだ席が空いています!もったいないお化けが出ますので、空いている人ははてなにGO!