2012年1月31日火曜日

node.js で 出来るだけ最新の node-websocket-server を使う。

で、結局、まぁ、なんというか、やり始めているわけなんですが。
ていうか、サーバの実装は、終わったので、
あとは動かすだけなんですが。

で、Socket.ioがうまく扱えなくてトラウマな俺は、
node-websokcet-server !!君に決めた!!って感じなのですが、

https://github.com/miksago/node-websocket-server

ここが本家にも関わらず、新しい WebSocket に対応しているのかが微妙な感じみたい。


https://github.com/VanCoding/node-websocket-server

こっちのが新しいみたいなので、こっちを使いたいけど、
npm すると、古い本家のほうがインストールされちゃうっぽいので、

https://github.com/VanCoding/node-websocket-server/downloads

ここから新しい(みんなの) tarball をダウンロードして、短い名前にリネームして (x.tar.gz とか)
どっか適当なサーバ( http://www.example.com )にその (みんなの) tarball をアップロードして、

npm install http://www.example.com/x.tar.gz

とかやれば、 無理矢理インストールできます。
動くかどうかは、知らないけど、no.de 上では動いてます。
というか、止まっていません。まだクライアントと接続すらして無いけど。

2012年1月30日月曜日

Titanium Mobile で WebSocket

できねーだろーと思ってたけど、ありました。
いや、まだ動かしてないけど。

http://blog.masuidrive.jp/index.php/2011/12/04/socket-with-titanium/
https://github.com/masuidrive/ti-websocket-client

が、元になってるやつで、

↑を改良したものが、
https://github.com/nowelium/socket.io-titanium
みたい。

WebView 内では WebSocket 使えたかも、とは思ったけど、
TitaniumMobile 自体では、WebSocket っていうプロトコルに対応してないので、
実装したみたいです。てか、MoonGift で記事を見たな。

Beholdr に関して考えると、WebView 上に更新内容が表示されるようになってるから、
本体(Android アプリ 自体)のほうでそれをやる理由もあんまりないのかも知れないけど、
なんか、利点とかあるかなー。うむー。

WebSocket といえば、絡めて使いたくなるのが、StreamAPI。
Twitter の StreamAPI は、ここが詳しかった。というか、わかりやすかった。

http://www.antun.net/tips/api/twitter.html

Facebook、FriendFeed も確か、StreamAPIがあった気がするなー。どうだっけ。


こんな感じにして、

Android 端末は、ユーザ情報とかを持ち運ぶだけにして、
今まで端末でもやっていた更新のデータを持ってきたりとかを、
サーバサイドにやらせりゃあいいのか?も?し?れ?な?い?でもない?
なんか、もう、全くの別なアプリになる気がするんだけど、
まぁ、便利ならいいか。

こうやって図にしてみて、無理が無いから、出来るよな。うん。
まぁ、なんとなく怖いかも、なのは、
RSSと2ちゃんねるは別な方法を使うとして、
タイムライン取得してるWebサービスが14個くらいあるから、
1) 1ユーザにつき14個のループが最大でサーバで発生する事と、
2) ユーザAに渡すべき更新内容がユーザBに渡ってしまわないか
っていうことだなー。

1) は、今Beholdrダウンロードしてる人が全然いないから大丈夫。
2) は、WebSocketを信じようぜ!って感じか。


サーバサイドでIDとかパスワードとかアクセストークンとか保存すれば、
Webアプリ化することも出来るし、
Webアプリとしてユーザアカウントを発行したりすれば、クライアント開発も、凄い楽なんだろうけどなぁ。
そこで、OpenIDなのか。BrowserIDなのか。

なんか、発想が、逆だよな。
普通、Webアプリを作って、それを便利に使える携帯端末用クライアント作るんだろうけど、
携帯端末用クライアントがあるから、Webアプリも作りますっていうのは。
あー。でも、Instagram とか、こんなニュアンスだよね。

色んなサービスがOAuth対応してくれりゃ、アクセストークン保存するだけだから、
気持ちが楽なんだろうけど、ベーシック認証のみのサービスがあるから、なんともねぇ。

WebSocket っていうところから、夢が膨らんだり、萎んだりしたのでした。

[Android][App][versionup]Beholdr 1.3

ソーシャルフィードリーダ Beholdr の1.3を公開しました。
主な更新内容は、 mixi のタイムライン表示に対応しました。
また、mixiVoice の投稿に対応しました。

あ、ロケタッチのGPSやるんだったー。あとGoogle+の投稿と+1もだ。
それやったら、コードを綺麗にして行こう。

目に余るほどのぐちゃぐちゃぶりだもんなー。
あとは、電池減るの早いよ対策とかか。
更新を取得する部分とかがネックっぽいので、
そこらへんかなー?
RSSを10分に一回ゴバっと取りに行くようにするだけで違うかなー?
初回起動時がやばいよね。そうすると。
初回だけ、今から10分前より後に書かれたやつにすればいいのかな。

ん~。悩むわぁ。

2012年1月29日日曜日

続々・Titanium Mobile で mixi Graph API

おめたんコメントを、FacebookとかGoogle+とかWassrとかでいただきました。
ありがとうございます!
同居している人達からは、何もお祝いを言われていないまま、誕生日が終わろうとしています!やったね!
あ、昔の同僚がおめでとうとLINEで言ってくれました。ええ子やで。keiちゃんええ子やで。

というわけで、mixi Graph API で文字化けする原因?と、対処法がわかりました~。
なんで文字化けしてしまったのかは、わからないんだけど、
(UTF-8エンコード宣言しているにもかかわらず、EUCで書いて保存しているっぽいのではと思う)
前回のエントリで紹介した jcode.js と utf8.js (?) 的にいうと、

var str = "わっかっさー!わっかっさーってなぁんだっ!";
str = _to_utf8(_to_euc(str));

こういうエンコード状態になっているみたいです。

なので、

str = _from_euc(_from_utf8(str));

こうすることで、元に戻ります。

で、きれいに文字が表示されるようになりましたよーひゃっほーう!

で、mixiボイス投稿とmixiボイス返信とイイネ!を実装しようとしたんだけど、
投稿についてはできるんだけど、
mixiボイス返信とか、イイネ!が出来ない。
理由は、UpdateAPI でデータを取得すると、
VoiceAPIで取れば取得できる、POST-ID という一意なIDが取得できないため。

http://developer.mixi.co.jp/connect/mixi_graph_api/mixi_io_spec_top/voice-api/

これがないと、返信もイイネも出来ない。
ていうか、mixi のWebサイト上だと、mixi チェックだろうが日記だろうがなんだろうが、
イイネ!出来るはずなのに、 UpdateAPI に POST-ID が無い限り、どうしようもない。

UpdateAPI で取得できる JSON データ上で、id というカラムはあるんだけど、
中身が id ではなくて、URI になってる。

http://mixi.jp/view_check.pl?post_time=20120129202439#owner_id=cqs7s4qrou1ae_1327836279

アクセスしても、データがありませんと言われる。
これに対して何かアクションを起こせば、POST-ID が取れるのなら、取りに行くんだけどなぁ。
あ。でも、待てよ?

VoiceAPI の POST-ID のサンプルを見ると、
[
  {
    "id" : "1FZ3P4ACUWBBC-2010061010321",
    "created_at" : "Thu Jun 10 01:32:13 +0000 2010",
    "text" : "つぶやきの本文",
    "user" : {
      "id" : "1FZ3P4ACUWBB",
      "screen_name" : "Becky",
      "profile_image_url" : "http://profile.img.mixi.jp/photo/user/1FZ3P4ACUWBBC_301280930.jpg",
      "url" : "http://mixi.jp/show_friend.pl?uid=1FZ3P4ACUWBB"
    },
    "photo" : [
        {
            "thumbnail_url" : "http://id.photo.mixi.jp/....",
            "image_url" : "http://id.photo.mixi.jp/....",
        }
    ],
    "favorited" : false
  }
]
こうなってるので、
URLを分解して、 post_time= と owner_id = をくっつけりゃいいじゃんねぇ。
でも、なんかよくよくみると、 user.id (1FZ3P4ACUWBB) と id (1FZ3P4ACUWBBC) だと、
id の 方が、最後にCが余計だよね。関係あるのかな?なんでもいいからCつけてみりゃいいか。

    var id = "http://mixi.jp/view_check.pl?post_time=20120129202439#owner_id=cqs7s4qrou1ae_1327836279";
    id = id.replace("post_time=","").replace("owner_id=","").split("?")[1].split("#");
    id = id[1].split("_")[0].toUpperCase() + "C-" + id[0];
    alert(id);

こんな感じでどうだろ。やってみよう。
やってみたけど、ん~。NotFoundって言われるわぁ。
ん~。困ったわおん。チョイ調べる。

続・Titanium Mobile で mixi Graph API

あ、誕生日です。ありがとうございます。
31歳になりました。
コメント欄に皆さんからの温かい言葉が沢山で、とても嬉しいです。



ス パ ム コ メ ン ト す ら 来 な い け ど ね 。

はい。というわけで、mixi の文字コードの問題が解決しそうなので、書きます。
色々とインターネットを調べたら、

日本語URL変換ツール: ドメインのピュニコード(Punycode)変換とUTF-8など文字列のエンコード・デコード

こういうところがあって、どーやってんだろーと思って、ソースを開いたら、
jcode.js って書いてあったので、それでぐぐったら、

Unicode と JIS / EUC / シフトJIS 間の変換

こういうのがありました!

追記!こっちもです!

Unicode ⇔ UTF-8

ソースコードの使用、配布に制限はありません。ご自由にお使いください。

って書いてあるから、使っていいのであろう。ありがたや。
結局自分の力では解決できなかったのである。なさけねーなー。
こっちのコードを見たら、ecl.jsより判りやすかった。
でも、結局判らないけど(笑)
テーブルから文字列を引っ張ってきたりしてたりするのとかは判るので、
なんか、うん、えーと、わからない。でも、わかる。

取り合えず、なんとかなりそうだ!ということで。

Titanium Mobile で mixi Graph API

というわけで、取得してデータを表示はできました。
ロケタッチと同じく、OAuth 2.0 な感じなので、
特段何か複雑だったわけではないものの、前回のエントリに書いたように、
AccessToken の有効期限が短いので、
mixi だけ、更新をとりに行く前に、RefreshToken を使って、 AccessToken を最新のものに書き換える処理を入れるようにしました。

で、ちゃんとデータを表示は出来るんだけど、
何故か、文字化けする…おいおいおいおい!

そういえば、なんか文字コードがどうとか書いてあったなーというのを思い出した。

API共通仕様

下のほうにある、絵文字のところで、文字コードの部分があったので、
emoji_carrier=au&emoji_charset=utf8
にしてみたんだけど、変わらず文字化け…おーまいがーっど。
絵文字のキャリアをAUにしたのは、AUはお猿さんの絵文字が可愛いからです。はい。

だいたい、JSONってUTF8以外はダメでしょ?そういう決まりじゃなかったっけ?
なんで文字化けするのかわからん。わーけがわからん。
ブラウザでチェックした、前回のエントリの時には
文字化けなんかしなかったのに、である。

これ、escape() とか そういうので文字化けしてるように見えるってもんじゃないもんなー。
Titaniumに問題があるのだろうなー。うむ。

ちょっと調べてみるけど、なんだかなーもう。
で、調べたら、

Escape Codec Library

これで出来るみたい。

ライセンスとか、どうなっているのであろうか…
転載可としか書いてない…うごー。これ困るパターンのやつじゃないですかー。
ソースを ecl.js のソースを見たけど、意味がわからない。
コード圧縮とか、難読化とか、そんなレベルじゃねー。すげー。これ。感動した。

とりあえず、別な方法を模索しますわー。

2012年1月28日土曜日

mixi のGraphAPIがおいおい…な件と、オレオレJSON.stringify

ていうか、仕様書?のとおりにパースしようとしたら、
なんか undefined 出まくりで、どーなってんだよー!となった。
Windows版の Safari の 4.0 ~ 4.0.3 までは、SSLなJSONデータがJSONPじゃなくても取れるので、
それでデータを持ってきて、データを確認しようと思ったんだけど、
そういや、JSON.stringifyとか出来ないんじゃね?ってことで、
自分で オレオレ JSON.stringify 的なことが出来る関数を組んで、
データを文字列化して確認した。

オレオレJSONstringify
var jsonStringify = function(obj){
    var str = "";
        str += (obj.length) ? '[' : '{';
    for(var i in obj){
        str += (str.length == 1) ? '' : ',';
        if(typeof(obj[i]) == "object"){
            str += (obj.length ? '' : '"' + i + '":') + arguments.callee(obj[i]);
        }else{
            str += '"' + i + '":"' + obj[i].replace(/"/gi,"\\\"") + '"';
        }
    }
    str += (obj.length) ? ']\n' : '}\n';
    return str;
}

使い方は、
$.getJSON(url,function(json){
 var str = jsonStringify(json);
});
とかやってください。


ザックリ書いたので、エラーになっちゃうこともあるかもしれないけど、
一応、
http://braincast.nl/samples/jsoneditor/
http://jsonlint.com/
どっちでもVaildなJSONってなる。
複雑なJSONだと、エラー出るかも知れないので、あまりアテにしないでね。 


で、GraphAPIの仕様書みたいのだと、
published になってるのが、postedTime になってたり、
url になってるのが、 link になってたり、
id の部分が mixi のid (http://mixi.jp/show_friend.pl?id= 以降の数字部分)じゃなかったり、

{
"link":"http://mixi.jp/redirect_with_owner_id.pl?b=http%3A%2F%2Fmixi.jp%2Fview_check.pl%3Fpost_time%3D20120126054610&k=owner_id&v=cqs7s4qrou1ae",
"postedTime":"2012-01-26T05:46:10+09:00",
"object":{
"link":"http://mixi.jp/redirect_with_owner_id.pl?b=http%3A%2F%2Fmixi.jp%2Fview_check.pl%3Fpost_time%3D20120126054610&k=owner_id&v=cqs7s4qrou1ae",
"postedTime":"2012-01-26T05:46:10+09:00",
"targetUrl":"http://b.hatena.ne.jp/entry/77604833#mc?u=psychedesire",
"objectType":"bookmark"
},
"verb":"share",
"id":"http://mixi.jp/view_check.pl?post_time=20120126054610#owner_id=cqs7s4qrou1ae_1327524370",
"title":"ドラマーの動きを可視化したドラムソロ(動画) : ギズモード・ジャパンをブックマークしました。",
"actor":{
"link":"http://mixi.jp/show_friend.pl?uid=cqs7s4qrou1ae",
"objectType":"person",
"id":"http://mixi.jp/show_friend.pl?uid=cqs7s4qrou1ae",
"image":{
"width":"180",
"url":"http://profile.img.mixi.jp/photo/user/cqs7s4qrou1ae_3889300265.jpg",
"height":"174"
},
"displayName":"pdyh"
}
 

こんな感じですね。俺がはてなブックマークしたやつの、mixi チェックのデータ。
一見すると、 obj["id"] にもURLがあって、
http://mixi.jp/view_check.pl?post_time=20120126054610#owner_id=cqs7s4qrou1ae_1327524370

それを開けばいいのかなーと思うけど、 これを開いたら、エラーって言われます。
あと、mixi の説明のところで、photo photoalbum って objectType のところにあるんだけど、
activitystream のところでは、 photo photoalbum から image に変わりましたって書いてあったんで、
mixi の人は書き換えたほうがいいんじゃねーの?と思います。

あと、認証関係も厳しい(facebook とかに比べれば…)感じで、
access_token の有効期間が短くて、
15分以内にリフレッシュトークンっていうのを使って、トークンの再発行をしなきゃだめみたいです。
Facebookとか別にトークンそのままで大丈夫なんだけどなぁ。
こないだのFacebookでタイムラインだけ取れないのもこれが原因なのかな?
調べたら、1時間くらいで取得できなくなるとは書いてあるけども。

Facebookのオフラインアクセストークンを得る方法

じゃあ、なんで俺だけずっと同じトークンで取得できてるんだろ。
開発者アカウントになってるからかもしれないな。
じゃあ、投稿の時だけ、俺以外の人でも、古いトークンで動いていたのだろう… Facebook。謎。
一応書き加えておこう。
scope=offline_access ね。
mixi でも使えないのかな?この scope と思って調べてみたけど、該当無し。
無理やり scope に offline_access って入れたけど、そしたら pin が返ってきませんでしたーワハハハハ。死ね。
リフレッシュトークンも有効期限あるとか書いてあったしさぁ。まぁ、セキュリティを考えたら、それが普通なんだろうけど、はぁ。


リフレッシュトークンでアクセストークンを書き換えてから、json 取りにいくようにすればいいか。めんどくせーから。
と思って調べてみたら、


リフレッシュトークンにも有効期間があるんです


mixi のOpenGraph のサンプル書いている人だ。Gitで見た。ここに良いことが書いてあった。
しかし、OAuth 2.0において「リフレッシュトークンにも有効期間がある」ということを意識していない開発者は多いかもしれません。実際には、ユーザが認可画面で同意し た内容に影響を受けるのは、アクセストークンの有効期間ではなく、リフレッシュトークンの有効期間です。つまり、開発者はアクセストークンの有効期間切れ を意識するだけでなく、リフレッシュトークンの有効期限切れに関しても意識をする必要があるということです。
mixi Graph APIを利用する場合、ユーザの認可画面には常に同意するかどうかを指定するためのチェックボックスがあります。このチェック状態に応じて、リフレッシュトークンの有効期間が決定します。
これかっ!Facebookのトークンも、俺だけ執行しなかった理由がわかったぞい!
じゃあ、ログインしっぱなしにすれば、いちいち認証エラーにならないぞーって書いておけばいいのね。
セキュリティリスクについても書いておきつつ。
イエイイエイ。OAuth系の認証のやつは、全部それが出てくるようにしたらいいですよねー。


おっしゃー。それじゃあBeholdrで mixi 見れるようにしよう。

2012年1月27日金曜日

Beholdr課題

ん。設定画面から戻っても、購読のループがそのまま続くようにしたんだけれども、
なんかそれはそれでバグる。2重に起動してる状態になってる。
あれれ~。あ、直せる。了解。あほだなー。

あと、データの取得部分をWebViewではなくてJAVAにやらせているのだけれど、
よくわからないタイミングで、ネットワークエラーというか、
HTTPClientが死ぬ。多分メモリ不足になってる。
メモリを開放するように、
Webサービス取得、RSSの取得、2ちゃんねるの取得の3つのスレッド(敢えてスレッドと書こう)の
それぞれのタイミングをずらしたりしているのだけど、
(TitaniumはJavascriptなのでこう書くけど、)setTimeout()してても、あんまりメモリ開放してくれない。
これはブラウザでも同じだった気がするので(最近そういうテストして無いけど)、
なんかうまい方法を考える。

本体側がデータ取得をしているので、3つのスレッドがそれぞれ7回ずつ計21回データ取得を試みたら、
全スレッド終了して、WebViewでタイマー発動させて、
メモリ開放したであろう頃合に本体側を再起動させる感じだろうか?
それでメモリ開放されるんなら、だけど。

あと、Facebookで取得が出来ないことがあるようなので、
確認しているけど、うむー。再現しない。
投稿が出来るようなので、そこがまたひとつのラビリンスである感じ。うむー。
問題が起こるかもしれない箇所を見つけたので、そこを修正はしてみたけど…

バッテリー消費って、どうやって抑えるんだろ。

2012年1月26日木曜日

[Android][App][versionup]Beholdr 1.2

祝!ブログの記事50本目!

Beholdr 1.2 を公開しました。

主な変更点は、
・RSSのプリセットにネタフル様を追加
・Google+ のタイムラインの取得
・ロケタッチのタイムラインの取得

となっております。
ネタフル様がRSSのプリセット登録を許可してくださいました。
とってもありがたいです。ありがとうございます。やったね!
エロイ写真集の情報ばっかり見てます。最高です。

Google+については、散々ブログに書いていた、非公式APIを使っておりますので、
ここにある使用上の注意を読んでから使って欲しい感じです。
まだ+1とか、投稿はできないです。
非公式APIから出来るのかなぁ?ソースよく読んでないや。
できなかったら、どうにかしよう。
非公式APIが不安定、というか、投稿される内容によって、
JSONがパースできないとかが、やはり発生しているみたいなので、
早く公式のAPIでタイムライン取得できないかなーと思いました。

ロケタッチのAPIを追加しました。おー。らいぶどあー。
しかし、タッチ!はまだできません。 悲しいことです。タイムラインを取得するのみです。
TitaniumでGPSとかのやりかたは調べたので、やってみます。
lat と lng 投げて、どこにたっちっちするかを選んで、また投げる感じすよね?
GUIだけだねーめんどくさそーなのはー。
でも、面白そうだし、やってみよう。

ロケタッチのAPIは、FacebookみたいなOAuth2なので、
Facebook用のやつをいじったら、なんかそんなに難しくなかった。
でも、AccessToken貰うところがJSONだったので、ちゃんとAPIリファレンス読んでなくて、
認証できねーっつって、ピヨピヨしてた。
そのような感じです。

というか、全く関係ないんですが、
今日(というか、昨日1/25)はこのブログのPV数が普段の3倍近くありました。
(PV数だけどね。100件くらいあった。)
最近、blogger では、どんなURLかは書かないけど、
ロシアとかからリファラスパムが凄いので、その関係かな?とは思うんだけど、
やっぱり数が合わないんだよなぁ~。なんだろ?まぁ、いいんだけど。

2012年1月21日土曜日

TitaniumMobileを使っていて、emulator-arm.exe がどうしても強制終了してしまう時の対処法

最近、なんかとにかくemulator-arm.exe が強制終了してしまいます。
TitaniumMobile の色んなバージョンを入れたからかもしれないけど。

で、多分、『emulator-arm.exe 強制終了』で検索すると、
メモリが足りないからだから、再起動しろって書いてあると思うんですけど、
再起動してもダメな時の対処法です。

AndroidSDKの中に入っている、AVDマネージャを起動して、
TitaniumMobileで使っているAVDを削除してください。
もちろん、AVD上に保存していたデータも消えます。Ti.App.Properties.setString("hoge","hugahuga");とか。
一応バックアップを取るなりしておいたらいいのかもしれないですけど。
まぁ、エミュレータ用のデータだから、ねぇ。
そこらへんはお好みで。

それで動かないならば、SDKをもう一回インストールしなおしてください。
それでダメなら、知りません。

続々々・Titanium 1.8 のHTTPClient で Could not find class 'org.apache.http.entity.mime.content.StringBody' というエラー

余裕でさっき書いた文章は嘘っぱちのクソ文章でした。ごめんなさい。
plusapi.js は直さなくてもいいです。多分。
server.js のContent-Length がちゃんと指定されてないから問題なのだみたいでした。
YungSang はちっとも悪くないのである。俺はやっぱりだめな男だ。ごめんねYungSang。

var body = JSON.strigify(json) したもののバイト数と、
body.length が同じだと、エラーは発生しないけど、その誤差があると、
JSONファイルが正しく外に出ないで、エラーが出るみたい。

というわけで、server.jsの下のほうを

// 改行とスペースを改行だけにする
        while(body.match(/\n\s/gi)){
            body = body.replace(/\n\s/gi,"\n");
        }
// 改行を取り除く
        body = body.replace(/\n/gi,"");
// バイト数を得る(後述)
        var bodyByte  = (function(body){
            var c = 0;
            for(var i = 0,l = body.length; i < l; i ++){
                c += (escape(body.charAt(i)).length < 4) ? 1 : 2;
            }
            return c;
        })(body);
// バイト数とbody.length の差を バイト数に追加。
        bodyByte += (bodyByte - body.length);
// ヘッダをセットして送信
        res.header('Content-Type', 'application/json');
        res.header('Content-Length', bodyByte);
        res.send(body);


改行を取り除く辺りが必要なのか否かは、ちょっと不明。
取りあえず、そうやったら動いているので、そうしています。
正規表現を理解していないのが露呈している感じです。

で、バイト数を得るってところは、

文字列のバイト数を求める

ここを参考にしました。無駄に無名関数。
というわけで、UTF-8コードにしなくても、activity.access をいじらなくても、データが取れました。
よかったよかった。ありがとうYungSang。グレイトフル・リスさん。

続々・Titanium 1.8 のHTTPClient で Could not find class 'org.apache.http.entity.mime.content.StringBody' というエラー

というわけで、全ての原因がわかったー!のである?かも。
着地、JSONが壊れている?のが原因だった。
ていうか、
try{var json = JSON.parse(str);}catch(e){alert("dame-");}
て、やってなかったから、ハングアップしてたんだけども。

取りあえず、前回書いたUTF-8コードに置き換えて、
更にescape(responseText)して、WebViewにぶん投げて、
WebViewのjQueryで$("body").html(escapedJSON);ってして、結果を見てみた。
Stringが壊れてるってなって、どんなデータなのか把握も出来ない感じになるので、
そこが困った。

対処法としては、 items[i].access が今回変になるのを確認したので、
plusapi.js の
1023~1027行辺り の access{} をコメントアウトして、
1152行辺りに、activity.access.items.push();しているIFが3つあると思うんで、
そのIFを3つ全部コメントアウトしたら、取りあえず大丈夫になった。
でも、今一旦動くだけで、
なんか例外的に変なものが投げられたりすると、JSONパースエラー起こすかもなーとは思う。
細々書き直していたので、行数は目安で。

でも、この、activity.access.items.push() のところ、別に変になる理由ないんだけどなー。なんなんだろ?
わけが判らないなー。
オブジェクトの{ } がちゃんと閉じられてなかったんだよねぇ。謎。

前回だったか、Content-Length : body.length ってサーバ側でやってて、
クライアント側でresponseText.length ってやったときの、数字が違うことがあったりした。

xhr.onload = function(){
 var contentLength =  this.getResponseHeader("Content-Length")
 var bodyLength    = this.responseText.length;
 Ti.API.info("contentLength - " + contentLength);
 Ti.API.info("bodyLength - " + bodyLength);

}

Titanium側でこんなのやったんだけども。
うむー。わけがわからないなー。まぁ、とりあえず、一旦動くようになったので、報告でした。

全体的なまとめとしては、
 サーバ側
  server.js
   ・ res.header('Content-Length', body.length); をつける。
   ・ if (req.query.callback) {} をコメントアウトする(俺だけ)
  plusapi.js
   ・ 前の記事の utf8ize() で全部の文字をUTF-8コードにしておいた(必要ないかも)
   ・ activity.access オブジェクトを全部削除してみた。
 クライアント側
  ちゃんとJSONは try{} のなかでパースしましょう。基本です。

こんな感じでした。

javascript で 文字列 をUTF-8 コードに変換する方法

UTF-8 コードって、 &#x123;  こういうやつのことです。
実は、

UTF8/16 | URL Encode / Decode

このライブラリを見つけたんだけど、配列で戻ってきてしまったりで、
さっくり使える感じではなかったので、
参考にしつつ自分でやってみました。

/*
 * Return UTF-8 Code.
 * ********************************************************** */
var utf8ize = function(str){
    if(!str) str = "false";
    if(typeof(str) == "function") return;
    if(typeof(str) == "object") str = JSON.stringify(str);
    if(typeof(str) == "undefined") str = "undefined";
    var l   = str.length;
    if(!l || l.length == 0) str = "undefined";
    var res = "";
    l = str.length;
    for(var i = 0;i < l;i ++){
        res += "&#x" + str.charCodeAt(i).toString(16) + ";";
    }
    return res;
}


多分、 boolean true の時は、 str = "true" に勝手にしてくれるでしょう…してくれないかも。
まぁ、最悪 !l のところでなんかうまいことやってくれるでしょー。
なんか、 typeof str == "function" の時も微妙だなー。

if(typeof(str) == "function"){
 var func = str();
 arguments.callee(func);
 return;
}

とかでいいんじゃないっすかね?気合入れてやるのであれば。
なんか、色々、抜けがあったりするんだろーなーとは思いつつ。

UTF-8コード表(1)

一応、こういう感じになるっぽいです。
日本語でしかテストしてませんが、多分動くと思いますよー。わからんけど。

2012年1月19日木曜日

続・Titanium 1.8 のHTTPClient で Could not find class 'org.apache.http.entity.mime.content.StringBody' というエラー

というわけで、前回の続きを延々と悩んで色々とやっていた。
なにをやっていたかは、
ここら辺を見ると判ると思いますが、なんか、試行錯誤過ぎてワロタ。


前回の記事では、TitaniumMobileのバージョンを 1.9.0 に上げるというところまでやった。
で、そのあと、サーバが Unavailable ってなってて、変だって書いたんだけど、
どうやら JSON を取りに行くたびにサーバが落ちるらしい。
node.js は、 forever という npm モジュールを使わない限り、
自動的にサーバが再起動したりしない(はず)なので、
JSONを取りに行って、サーバが処理できなくなって落ちて、
サーバが落ちたのに気づかずもう一回取りに行って、ReadyState3で止まるというわけみたい。

で、それがわかったので、サーバサイドに焦点をあてて色々やったんだけど、
まず、エラー文章を見てわかるとおり、StringBodyがなんか変だって書いてあるので、
そこをまず直した。

Google + 非公式API のnode.js のプログラムはこれ。 YungSang の美しいプログラムである。うっとり。
レスポンスを返している部分が、

function responseJSON(req, res, json) {
res.statusCode = (json.error ? json.error.code : 200);
res.charset = 'UTF-8';
res.header('cache-control',
'private, max-age=0, must-revalidate, no-transform');
var body = '';
if (typeof req.query.prettyPrint == 'undefined') {req.query.prettyPrint = true;}
if (typeof req.query.pp == 'undefined') {
req.query.pp = true;
}

if ((req.query.prettyPrint == true) && (req.query.pp == true)) {
body = JSON.stringify(json, null, ' ');
}
else {
body = JSON.stringify(json);
}

if (req.query.callback) {
res.header('Content-Type', 'text/javascript');
res.send('// API callback\n'
+ 'if (typeof ' + req.query.callback + ' == "function") '
+ req.query.callback + '(' + body + ');');
}
else {
res.header('Content-Type', 'application/json');
res.send(body);
}

こんな感じなんだけど、
ここのif(req.query.callback){}が誤動作しているのかTitaniumが悪いのか(多分Titaniumが悪い)、
TitaniumからJSONを取ろうとすると、

&callback=? としてないにもかかわらず、

JSONP、つまり、コールバックで受けようとする?のか、エラーを吐くので、
ここをまるっとコメントアウトしてやった。

つまり、
res.header('Content-Type', 'application/json');
res.send(body);
これだけになった。

で、Content-Length がないので、
res.header('Content-Type', 'application/json');
res.header('Content-Length', body.length);
res.send(body);


こんな感じにしてやると、とりあえず、エラーが収まって、データの取得(ReadyState4 200)になった。
のだが、今度は取得した JSON を JSON.parse したらエラーになる。
node.js で JSON.stringify すると、 "hoge": "huga" と ": " 余計なスペースが開くので、
これが原因か?と思ったけど、そうではないらしい。

node.js の JSON.stringify が、UTF-8 コードで文字列を返さないのが原因か?とも思ったけど、
Wassr の JSON も同様なのに動いているので、問題があるとも思えない。

というわけで、結果、お手上げでした。
んがー。悔しい。

あと、凄く動でもいい豆知識ですけど、

res.send(body);

この body って、

body = JSON.stringify(json);

json っていう {} を文字列に変換したものなんですよね。
で、

res.send(json);

という風に、javascript のオブジェクトを無理やり送信しても、
ちゃんとサーバが JSON文字列にして返してくれます。
凄く時間がかかるけど。まぁ、一応。

2012年1月18日水曜日

Titanium 1.8 のHTTPClient で Could not find class 'org.apache.http.entity.mime.content.StringBody' というエラー

Google+ から自分のストリームを取ってこれるようになったところで、
Beholdrを色々書き換えていたんだけど、

動かしてみたら、

 Could not find class 'org.apache.http.entity.mime.content.StringBody'

というエラーが発生してアプリが強制再起動。
強制終了はするものの、データは取得できている?のかな?
(ReadyStateが4にはなる。)
エラー文でググッてみたら、

Android: HTTPClient - send() creates benign error messages in log

発生理由は違うものの(form から post したらエラーが出るってことみたい)、
2012/01/13 にFixされたらしい。

1.9 系のビルドとなってしまうらしく、

http://builds.appcelerator.com.s3.amazonaws.com/index.html

ここにアクセスして、上のプルダウンを master にして、

現在の最新版 mobilesdk-1.9.0.v20120117114633-win32.zip をインストールして、
再度動かしてみたが、強制終了はしなくなったものの、
同じエラーでデータが取得できなかった。
(ReadyStateが 1 でエラーで止まったり、 3 でエラーで止まったりまちまち)

一旦、これまでSDKが 1.8 や 1.9 だったのを、1.7.5 に戻してみる。
そしたら、なんかさっきのエラー文章が出ない!やったー!と思ったけど、

Sending error Service Unavailable

で結局ReadyState 3 で止まる。
これはもう、間違いなく、サーバサイドの問題ですよね。

サーバサイドは、これまで書いてきた、

Heroku + node.js + Unofficial Google+ API

なので、多分、node.js つか、express が変なんだろうなと思います。
ちょっとめんどくさそうなので、一生懸命調べる。うむ。

2012年1月17日火曜日

PHP で Gmail からメールを送る

そんなわけで、PHPからメールを送ってみます。
方法論は沢山あるのだけれど、
PEARはめんどくせーなぁと思っていて調べたら、

PHPで日本語メールを送る – 応用編 (添付ファイル、HTMLメール)

こういう良い記事を見つけました。
で、 これを参考に、PHPから自分のGmailのアカウントを使って、
誰かにメールを送るプログラムです。

というわけで、PHPMailer をダウンロードしましょう。

require("class.phpmailer.php");
mb_language("japanese");
mb_internal_encoding("UTF-8");

// 添付ファイル このPHPと同じ階層にある myDir の中の test.jpg
$file   = "myDir/test.jpg";
$mailer = new PHPMailer();
$mailer->IsSMTP();
try{
    $mailer->SMTPAuth   = true;
    $mailer->SMTPSecure = "tls";
    $mailer->Host       = "smtp.gmail.com";
    $mailer->Port       = 587;
    $mailer->Username   = "usr@gmail.com";
    $mailer->Password   = "gmailPassword";
    $mailer->Subject    = "メールタイトルだー";
    $mailer->Body       = "メール本文だよー";
    $mailer->AddAddress("test@example.jp","誰彼様");
    $mailer->AddCC("cc@example.com","彼誰様");
    $mailer->SetFrom("usr@gmail.com","俺様");
    $mailer->AddAttachment($file);
    $mailer->Send();
}catch(phpmailerException $e){
    echo $e->errorMessage();
}catch(Exception $e){
    echo $e->getMessage();
}

こんな感じですね。
別に難しくもなんともないです。
mime_header とかほんとはやったほうがいいと思うんだけど、
やったらやったで文字化けしたりすることもあるみたいで、難儀な感じです。
そこらへんのやり方は、一旦参考にしたページを元に書いたほうがいいと思います。

PHP で画像を切ったりリサイズする。

で、PHPで画像を切ったりサイズを小さくしたりしたかったので、
そういうライブラリを探しました。

PHPでの画像のリサイズ、切り抜きが自由自在「class.image.php」

ここにあったやつを使います。

まぁ、書いてあるとおりにやればいいんだけど、
このままだと、ちょっと不都合もあったので、そこらへんも交えて書いていきます。

require("class.image.php");

// 小さくする画像の名前
$file  = "test.jpg";

// 小さくする画像のある場所。このPHPと同じディレクトリにある myDir の中の test.jpg
$path  = "myDir/".$file;

// ファイル名を . で区切る。
$exts  = explode(".",$file);

// 拡張子の部分を削除します
$dele  = array_pop($exts);

// 拡張子がないファイル名の部分を生成 この場合 test になる。
$we    = implode(".",$exts);

// 小さくしたあとのファイルの保存場所。この場合、myDir/thumb/thumb_test(.jpg) になります。
// 拡張子は、このクラスが勝手につけてしまうので、
// "thumb/thumb_".$file とやると、myDir/thumb/thumb_test.jpg.jpg というファイルになってしまいます。
$thumbPath = "thumb/thumb_".$we;

$thumb = new Image($path);
$thumb->name($thumbPath);
$thumb->width(100);
$thumb->save();

コメント欄にも書いたけど、ファイル名のまんまでやると、拡張子が2重になってしまうようなので、
そこだけ気をつけて使いましょうって感じ?
ちゃんとリファレンスを読んでいないので、なんか解決策あるのかもしれないけども。

PHPでAmazonS3へファイルをアップロードする

というわけで、FTPは諸事情あり諦めて、
AmazonS3を借りて、そこにファイルをアップロードし始めました。

PHPからAmazonS3へファイルをアップロードするやつは、

PHPからAmazon S3を利用するライブラリを3つ試してみた(うち一つは動作不可)
ここで紹介されていた amazon-s3-php-class を使いました。
Gitにファイルがあります。

紹介しているページにも書いてありますが、

require("S3.php");
// アップロードするファイル名
$file       = "test.txt";
// アップロードするファイルがあるローカルアドレス この場合 このPHPファイルと同一階層にある myDir というディレクトリの中の test.txt
$local_file = "myDir/".$file;

$s3 = new S3("アクセスID", "シークレットキー");
$s3->putBucket("アップロードするバケット名", S3::ACL_PUBLIC_READ);
$s3->putObjectFile($local_file, "アップロードするバケット名",$file, S3::ACL_PUBLIC_READ);

こんな感じで書いてあげれば良いです。
アクセスIDとシークレットキーは、



AWSにログインして、セキュリティ証明書をクリックして、





下のほうにあるアクセス証明書のところに書いてあります。
シークレットキーは クリックすれば表示されますよ。

そんな感じでした。

XREAやLivedoorBlog 等へ、PHP の ftp_put() からファイルのアップロードできない時の対処法

レンタルサーバのxrea.com や
LivedoorBlog の有料サービスで使用できるFTPサーバ接続へ、
PHPからファイル送信ができなかったのですが、それへの対処法です。
なかなか、PHPを使ってFTPサーバへファイルをアップロードしようという人もいないようで、
対処法が見つからなかったのです。

単純に
ftp_pasv($conn_id, true);

これをやればよかっただけでした。
ファイルパスとかも、どうやれば正解なのか良くわからなかったけど、
まぁ、とりあえず動きました。

    $ftp_server    = "ftp.example.com";
    $ftp_user_name = "ftpusername";
    $ftp_user_pass = "ftppassword";
    $conn_id       = ftp_connect($ftp_server);
    $login_result  = ftp_login($conn_id, $ftp_user_name, $ftp_user_pass);
    if((!$conn_id) || (!$login_result)){return false;}

    /* ここの第二引数の true が大事。これがないと、アップロードできないFTPサーバがあるみたい。 */
    ftp_pasv($conn_id, true);

    /* 実行されているPHPファイルと同一階層にある test.txt をアップロードする */
    $file = "test.txt";
    $local_file  = $file;

    /* FTP接続時に最初に開かれるディレクトリにアップロードする。 */
    $remote_file = $file;

    /* xrea の場合は、このように書くと、良いと思います。 uploadtest のパーミッションを707とかにすること。*/
    $remote_file = "public_html/uploadtest/".$file;

    if(!ftp_put($conn_id, $remote_file, $local_file, FTP_BINARY)) {
        print("---- uploadNG ----");
    }
    ftp_close($conn_id);

まぁ、結局、FTPは使わないことにしたのですけども。

Window + Heroku で node.js のアプリケーションを動かす

久しぶりのWebエントリーです。
こんにちは。

Beholdrに、Google+ を追加しようとしたのですが、
どうやら、非公式APIのアプリケーションサーバを立てなきゃならないっぽい?
ので、 Heroku というCloudのホスティングにそれをおいてみました。

やることの順番は、
1・WindowsでHerokuとやり取りできるソフトをインストール
2・インストールしたので、Herokuと通信できるように設定する
3・Git上にある、Google+ 非公式APIをGitを使ってダウンロード
4・ダウンロードしたやつをそのままアップロードしても使えないので、ちょっとファイルを追加する。
5・追加したファイルも含めて、Herokuへアップロードして、使えるようにする。

こんな流れです。ではザックリレッツドン

1・ ここ の Step2 のところのWindows用のインストーラをダウンロードしてインストールしましょう。

2・Win + R を押して、cmd.exe を実行
コマンドプロンプトが立ち上がるので、

heroku login

と入力。で、Herokuに登録したメアドとパスワードを入れる。
初回は、RSAとかいう、認証キーを作るみたい。あんまどうでもいい。

3・今回は、 Git にあるやつをコピってくるので、
git clone git://github.com/YungSang/plusapi.git
とコマンドプロンプトに打ち込む
そうすると、大概の人は、C:\Document and Setting\[usr]\
に、\plusapi というディレクトリが出来て、その中に、ファイルが入っているはず。

4・で、一旦ここでコマンドプロンプトから離れて、
(別にコマンドプロンプトからやってもいいけど)
そのC:\Doument and Setting\[usr]\plusapi に Procfile というファイルを作って、
そこに、 今回は、 web: node server.js と書いて入れておく。
 これは、Webサーバを起動したら、server.js を開いてねって意味らしい。

5・で、コマンドプロンプトに戻り、

 cd plusapi

 と入力する。
 で、

 heroku create [hogehuga] --stack cedar

 と入力すると、 hogehuga.herokuapp.com というWebアプリケーション作られる。
 単純に、

 heroku create [hogehuga]

 だと、Ruby on Rails 用の hogehuga.heroku.com という
 Webアプリケーションになってしまうらしく、それではだめっぽいので注意。
 で、無事に hogehuga.herokuapp.com が作られたら、


 git push heroku master


 とやって、なんか、エラーとか出なければ、大丈夫。多分。


 そんな感じでした!


あとは、hogehuga.herokuapp.com にアクセスしてなんかかんかしてください。


参考になったURL
node.jsをherokuに乗せてみた
Heroku + Node.js + ExpressでHelloWorldを書いてみた。

2012年1月14日土曜日

明日やること


Google+のアンオフィシャルAPI
http://plus.no.de/
アンオフィシャルだけど、公式API。明らかになっていないだけ。
仕様変更が怖いねぇ。まぁ、しゃーないかな。その辺。

ロケタッチのAPI
http://tou.ch/developer/api_common
http://tou.ch/developer/api_all?uri=home_timeline
FourSquareのAPI見ても、何がなんだかわからなかったからって、
ロケタッチにするわけではないんです。
あ~。位置情報とかも取得できるようなものを作らなきゃダメなんだな。
このAPIで投稿できるようにするとなると。

別件。LivedoorBlogのAPI
http://wiki.livedoor.jp/staff/d/API/AtomPub
残念ながら、画像はAPI経由でアップロードすることが出来ないみたい。
ん?待てよ。メールで投稿出来るよなぁ?
メールで投稿するときに、画像添付できるんなら、そうしよう。

2012年1月13日金曜日

node.js0.6.7 を Windows 環境で動かす

npmが使えるようになったっぽい?ので、
使えるようになったなーっていう。

http://nodejs.org/

からWindowsバイナリをダウンロードして、
インストールすると、なんとProgram Files にインストールしやがりました。勝手に。
ディレクトリ変えたい…まぁいいか。

で、喜び勇んでWin+Rキーを押して、 npm install jsdom とかやったら、
なんかエラーが出た。
node-waf の使い方が誤っています
みたいなのが出やがる。

なんぞ!と思って調べてみたら、

https://groups.google.com/forum/#!msg/nodejs_jp/_25pOkwEcag/Lw18uKhdfHQJ

あらまぁ。それは残念。
つか、めんどくせーな依存関係全部ダウンロードするの!ギビビビビ。

なんか、やる気を失ったので、VirtualBoxでUbuntu動かすよボクは。

2012年1月12日木曜日

Titanium Mobile1.8.0.1 にしたら apk のサイズが3倍くらいになった。

なんでやねん!な、な、な、な、なんでやねん!
まぁ、そういうものなんでしょうけども。

JavascriptエンジンをV8にしたからなのか、
なんなのかはわからないけど、
今までは3.5Mとかそんくらいだったのに、
1.8.0.1にしたら9.8Mくらいになった。

appceleratorのフォーラムにもあった。
http://developer.appcelerator.com/question/130536/android-1801-rhino-apk-size-way-too-big

Rhinoにしたら、更にサイズが膨れ上がるらしい…
あらまぁ~。まぁ、スマホだから、ファイルサイズあんまり気にしないけども。俺は。
他の人は気にするかもねぇ。

Titanium Mobile 1.8.0.1 で Ti.UI.currentWindow.close()が動かない

Ti.UI.currentWindow なんて使いたくねーなーとか思っていたんだけど、

Ti.App.addEventListener("hoge",function(){
var xwin = Ti.UI.createWindow();
});

とかやっちゃって、他のイヴェントからこのxwinを閉じたいときに、
Ti.UI.currentWindow.close(); ってやれば楽だわなと思ってて、
TitaniumMobile1.8にする前はこれで動いてたんだけど、
1.8から動かなくなった。
まぁ、別にいいんだけどね。
グローバルに変な変数が出来る羽目になるけど、

var xwin = "";


Ti.App.addEventListener("hoge",function(){
xwin = Ti.UI.createWindow();

});

Ti.App.addEventListener("moge",function(){
if(typeof(xwin) != "string"){
xwin.close();
xwin = "";
}
});



なんか、typeof() ~ のくだりが胡散臭いけど、
まぁ、動けばいいよね!
関係あるのか無いのか良くわからないけど、リンクを張ってみる。
調べても同じ現象が見つからなかった。
 activeTab returns undefined in 1.8.0.1

TitaniumのTi.UI.currentWindowという概念がよくわからない

そんな感じでした。

Titanium Mobile 1.8 からの変更点?アプリケーションの終了のさせ方が変わった?

今までは、
ハード(携帯端末)のバックボタンを押し、
表示される終了確認ダイアログでOKを押すと、

Ti.Android.currentActivity.finish();

が動くようになって、
タイトル画面に戻ったんだけど、
なんか、タイトル画面に戻らなくなった。

なんじゃそりゃ。どうすりゃいいんだよーう。
と思ったけど、仕方が無いので、
メインのウィンドウを閉じるようにした。

まぁ、バックボタンを押しまくると、最初のウィンドウに行き着くわけだから、
そのウィンドウ開いてるときにバックボタンが押されたら、

Ti.UI.currentWindow.close();

とか、Windowの変数名決めうちで閉じちゃっても、まぁ、どっちでも同じだろうなぁ。

あ、あと、前回の記事

Titanium の WebView で jQuery 読み込み時の遅延

で、2ちゃんねるとかRSSのクローリングが止まったって書いたけど、
理由は、何故かTitaniumMobileのバージョンを上げたら、
Android Emulator の仮想SDカードから setList("listname",arry) した内容が消えたためっぽい。
謎だなー。うむ。

あと、1.8からは、いろんなAndroid端末向けに、
スプラッシュ画像を作らなくてはいけなくなったみたい。
今まではひとつの画像で、勝手にサイズをリサイズして表示してくれていたんだけど、
それができなくなったのか、何からしらの設定を変えなくてはいけなくなったみたい。

まぁ、画像作ったほうが、早いかぁ。

Titanium Mobile 1.8 からの変更点?ビルドが進まない。

というわけで、Titanium Mobile 1.8 にしてみました。
JavascriptのエンジンをRhinoからV8に出来るというので、
興味津々です。

せっかくなので、

http://blog.livedoor.jp/techblog/archives/67023203.html

ここに書いてあるやり方で、
最新の1.8にしてからビルドしてやるー!と息巻いてみました。
普通Titaniumをアップデートすると、2011-12-22版の1.8になるんですが、
あえて2012-01-03版にしてビルド…

とビルドしてみると、エミュレータは立ち上がるけど、アプリがインストールされたりしているわけでもなく、
コンソールが止まっている…
なんでや!と思ってbuild.logをみたら

[ERROR] C:\path\to\titanium\Appname\Resources\_hoge.js is an invalid filename. Android will not package assets whose filenames start with underscores. Fix and rebuild.

ということで、ファイル名に_(アンダースコア)が入っていると、ダメみたい。
まぁ、アンダースコアとればいいだけだし、
あちらこちらで使われているファイルではなかったので、よかったんだけども、
どうやら、WebViewとかで呼び出すローカルの html ファイルにもアンダースコアがあるとダメみたい。
画像ファイルとか、Resource以下にあるファイル全部ダメなんじゃねーの?ひょっとして。
まぁ、俺は影響なかったからいいけどねぇ。

で、 今実際に、鬼のように無駄なコードだらけのBeholdrを動かしてみているんだけど、
確かにこれはキビキビ動くね!

さっくさくやん!さーーーーっくさくやん!

文字をでかくしてみた。これはいい。
TitaniumMobile使えないとかいった人とかは土下座してセルフフェラチオするべき。
なんか、安定してる。そんな気がする。ただ、そんな気がするだけだけど。
Network.createHTTPClient() が安定するようになったのか、
前は確実になんかのタイミングで通信できなくなってたんだけど、それがなくなった。
と思ったら、今発症したから、あんまり変わらないんだろうなー。
リクエストを44回送ったら出た。

なんか、コンソールに表示される文字も減った気がするんだけど、関係あるんかいな?
よくわからんなー。
あと、

jsValueToJavaObject returning null

これなんだろうね。

と思って、今気づいたけど、Webの更新の取得はしてくれてるけど、
RSSと2ちゃんねるの更新取得が最初の一回で止まっているっぽいね。これ。
んおーっと。これは謎現象。書き方が悪いんだろうなー。うむ。

色々探りながら、直して、Deployします!興奮してきた!

2012年1月10日火曜日

Titanium の WebView で jQuery 読み込み時の遅延

すげーハマってました。
なかなかどうして難しいですね。

なんだろう。単純に考えると、

var win = Ti.UI.createWindow();
var wv  = Ti.UI.createWebView({url:"html/test.html");
win.add(wv);
win.open();
wv.addEventListener("load",function(){
 wv.evalJS("testFunc()");
});

ってやれば、WebViewであるwvの読み込み完了時に、
WebView で読み込んでいる test.html に記述された testFunc() が実行されるんだけど、
その test.html を読み込んだからといって、
test.html で script src してる CDN 上の jQuery.js の読み込みが完了していないっていう場合があるっぽい。
testFunc内で、$ とか使っていて、jQuery の読み込みが終わっていなければ、当然実行エラーになる。

んで、最初はどうしたかというと、
html/jQuery.js みたいに、ローカルにおいて、それを読み込めばいいじゃん!って思った。
しかしながら、なんか、Titanium で アプリを Deploy (製品状態にコンパイルする)時に、
jQuery.js でコンパイルエラーみたいになってうまくいかなかった。
仕方が無いから、 html/test.html に、 jQuery.js の中身を書いてやれ!と思って書いたんだけど、
今度は test.html のコンパイルエラーみたいになった。
まぁ、読み込んでいたのが jQuery1.6.2 だったからなのかもしれないけど。

仕方が無いので、wv.addEventListener() を書き換えました。

var win = Ti.UI.createWindow();
var wv  = Ti.UI.createWebView({url:"html/test.html");
win.add(wv);
win.open();
wv.addEventListener("load",function(){
 var timer = setInterval(function(){
  var jQReady = wv.evalJS("$.isReady");
  if(jQReady){
   clearInterval(timer);
   wv.evalJS("testFunc()");
  }
 },100);
});

0.1秒毎にjQueryの準備が出来たかどうかを返す、$.isReady を WebView に投げて、
jQuery の読み込みが無ければ $ もなにも無いんで、何も返ってこないんだけど、
読み込みが完了したら true が返るので、
そしたらタイマーをはずして testFunc を実行するようにしてみた。
一応は、動いてはいるんだけど、大丈夫かなー。
Android は、なんだか動きが良くわかりません。機種ごととかによって違うのかもだし。

[Android][App][versionup]Beholdr 1.0.8

Android 用 ソーシャルフィードリーダ Beholdr のバージョン1.0.8 を公開しました。

・ Fav機能が動かなくなっていたのを修正
・ 更新時刻取得がおかしくなっていたのを修正
・ 一回開いた更新ボックスは色が薄くなるように改善
・ 一部Webサービス(*)でのReply機能の実装
・ 一部Webサービス(*)での新規投稿機能の実装
・ たまに起動したタイミングで下部のタブ以外何も表示されない現象の改善
 (* Twitter Wassr Identi.ca Friendfeed はてなハイク に対応済み)

以上に対応しました。
いよいよもって、投稿機能がついてしまい、
ソーシャルフィードリーダでは無くなって来てしまいました。
まぁいいか。

Beholdr 次回バージョン予告

1.0.8 の予告です。

・ Fav機能が動かなくなっていたのを修正 (済)
・ 更新時刻取得がおかしくなっていたのを修正 (済)
・ 一回開いた更新ボックスは色が薄くなるように改善 (済)
・ 一つ一つの投稿にピンを立ててローカルのSQLiteDBに保存出来るようにする
・ 一部WebサービスでのReply機能の実装 (済)
・ 一部Webサービスでの新規投稿機能の実装
・ たまに起動したタイミングで下部のタブ以外何も表示されない現象の改善 (済)
 (やっとエミュレータでも同じ現象が再現した…しかもくだらない理由…死にたい…)

2012年1月7日土曜日

Tumblr でAPIからReblogできねー

一回、出来るようなブログを書いたけど、
着地できなかったので、消した。

なんか、BadRequestって言われるのである。
Favは出来るのに、何故なのだろうか。

わからん。心からわからん。

2012年1月6日金曜日

[Android][App][versionup]Beholdr 1.0.5

Android 用 ソーシャルフィードリーダ Beholdr のバージョン1.0.5 を公開しました。
Facebookのいいね、
Tumblr、Flickr、TwitterのFavorite、
TwitterのRetweetが出来るようになりました。

TumblrのReblogも出来るようにしたかったのですが、
送るパラメタがめんどうなので、次回以降に回します。

また、Flickrの時刻の取得がおかしかったのを修正。
extras=date_upload で貰っておいて、 json[i]["dateupload"] で表示とか意味わからん。名前を統一しろ。
あと、APIリファレンスに載ってないのとかがあるっぽい?
Flickrのアバターの画像(ユーザのアイコン)を貰ってくるのに、
icon_farm と icon_server ってのと、ユーザの固有IDが必要なんだけど、
APIリファレンスのところにはextrasで貰える情報には、icon_server しか載ってない。
extras=icon_farm,icon_server で拾ってこれます。
で、
"http://farm" + json[i]["iconfarm"] + ".static.flickr.com/" + json[i]["iconserver"] + "/buddyicons/" + json[i]["id"] + ".jpg"
でユーザのアバターアイコン画像になります。簡単に言うと。
リファレンスにはJPGきめうちになってるんだけど、PNGとかの場合もあるのかな?
FlickrのAPIリファレンスのところは、古い情報のままになってるので、怖いです…

あと、Twitterから貰ってくる更新数を100にしました。
200まで取得できるんだけど、表示するときに重いので、一旦100で様子見です。
俺の環境(AUのINFOBAR)だと、ここら辺できつい感じ。

Titaniumで作ると、メモリ関係を自分でどうこうすることをしなくて良い分、
メモリ関係を自分でどうこうできないので、
メモリを食わないようにできるだけ書き換えて行きたいと考えております。はい。

ソーシャルフィードリーダなので、
投稿とかしないでおきたいなーと思っていたのですが、
ふぁぼれるようになっちゃったし、やっぱ、レスとかしたいよねーと思い、
投稿も出来るようにします。
あと、Posterous の更新を拾ってくるのと、
Gmail のメールも拾ってこれるようにしようかなと思います。
PosterousはBasic認証がOKのようなので、めんどうだからそうしようかと思います。
Gmailは、めんどくさいGoogleさん仕様(w)のOAuthだったはずなので、
あー。どうしようという感じ。
Tumblr、Flickrのために、BirdHouse(TitaniumでTwitterのOAuthを楽にするやつ)を書き換えたので、
そのまま使えねーかなーという感じ。

あと、最後ですが、イイアクセスさんが復活されまして、
あんまりにもうれしいので、オクトバさんに続き、RSSのプリセット登録をお願いし、許可いただきました。
ありがとうございます。UG-Kさん。これから日々サイトの更新頑張ってください。

2012年1月2日月曜日

[versionup]Beholdr 1.0.3

Android 用 ソーシャルフィードリーダ Beholdr のバージョン1.0.3 を公開しました。
WEBサービスクローリング部分の不具合修正をしました。
また、BASIC認証のWEBサービスでfavできるようになりました。

次あたりから、文字列投稿できるようにしたいなー。
ていうか、コードをきれいに書き直したい。うむむ。

[versionup]Beholdr 1.0.2

ソーシャルフィードリーダ Beholdr のヴァージョン1.0.2を公開しました。 2ちゃんねるとRSSのクローリングがダメダメだったので、挙動を直しました。 が、 なんか、端末によって、全然動きが違うみたいなので、 色々調整しなくてはいけないと思います。 いい加減、FavれたりとかRetweet出来たりとかも出来るようにしたいんだけれどもなぁ。 OAuthでPOSTできねーんだよなぁ。何故か。 NotFound食らうんだよなー。なんでだろ。調べる。