2013年も無事フリーランスとしてなんとか生き延びることができました。私のアプリを使っていただいている皆様、本当にありがとうございます!
せっかくなので今年1年をざっくりと振り返ってみたいと思います。
続きを読む※この記事のまとめは Twitter4JのSPDY対応について – TwitPane をご参照ください。
昨日の記事でTwitter4J+SPDYがSPDY通信しているか確認できると書いたのですが、非Android環境というか、Eclipseやコンソール上のjavaコマンドから実行するとどうにもSPDY通信してくれないので困っていました。
その後いろいろと調査した結果、どうやらJVMにnpn-bootというものが必要らしいです。
続きを読む※この記事のまとめは Twitter4JのSPDY対応について – TwitPane をご参照ください。
昨日の記事で公開したTwitter4JのSPDY拡張(twitter4j-spdy-support)ですが、本当にSPDY通信してるか心配ですよね。
色々調べてみたところ、一応下記のようなコードで Twitter オブジェクト(twitter)から SPDY のコネクションプール数を取得できることが分かりました。
続きを読む※この記事のまとめは Twitter4JのSPDY対応について – TwitPane をご参照ください。
Twitter4Jを次世代HTTPのSPDYに対応してみた。
OkHttpというSPDY&HTTP/2.0対応の超便利ライブラリがあったのでそれを使わせてもらっただけ。
でも後述の通りベンチマーク取ってみたら単独スレッドでの通信では速くないというかむしろ遅くなるんで、あくまでも実験的な実装ということで。
⇒Android/Dalvikだと TFJ-296 対応で強制的に http.keepAlive=false されていてコネクションプールが機能していませんでしたorz
⇒OkHttpのコネクションプールを別途設定することで高速化しました! (詳細は後ほど)
12/10(火)にTwitter公式アプリ(iOS/Android版)でDMに画像を添付できるようになりました。
この影響で、拙作のTwitPaneをはじめとする非公式アプリではDMの画像が取得できなくて空画像が表示されたり、レイアウトが崩れたりしてめんどくさいことになっています。
で、どうすりゃいいのってことで調べてみたんですが、下記で回答されていました。
@episod Taylor Singletary
We have no announced plans yet for providing a media upload endpoint for direct messages.We'll be releasing some documentation this week or early next on how to retrieve images attached to direct messages -- it's pretty simple, using OAuth 1.0A to retrieve the image instead of unauthenticated requests.
ドキュメント準備中ってことですが、つまりOAuth 1.0Aで取れるってことですね。
早速試してみたところちゃんと取れました。
Twitter4J的には内部メソッドのTwitterImpl.getを呼ぶだけでOAuth 1.0A経由になるのでこんな感じになりました。
// DM画像認証対応 MyLog.d("doDownloadImage, download image with twitter4j"); final Twitter twitter = TPUtil.getTwitterInstance(context); try { final Class<? extends Twitter> c = twitter.getClass(); final Method m = c.getDeclaredMethod("get", String.class); m.setAccessible(true); final HttpResponse res = (HttpResponse) m.invoke(twitter, rawImageUrl); // twitter.get(rawImageUrl); final InputStream is = res.asStream(); image = BitmapFactory.decodeStream(is); if (image == null) { // ダウンロード失敗 MyLog.w(" download twitter image, image load error [" + rawImageUrl + "]"); return null; } } catch (Throwable th) { MyLog.e(th); return null; }
Twitter4J v3.0.5でDM添付画像を取得してみた · GitHub
リフレクション使ってるのが汚いのでTwitter4Jにいい感じのインタフェースができるといいなぁ(メソッド名が思いつかない)。
それより(DM送信時の)画像添付APIが早く公開されるといいですねぇ。
ちなみにmixiのメッセージAPIが画像添付に未だに対応してない件、僕は忘れていませんからねw
(2013/12/17追記)
公式にアナウンスがありました。
この記事は Tizen Advent Calendar 2013 に参加予定の記事です。
どうもこんにちは。すっかり師走ですね。
Tizen関連で初めて来た方もいると思うので簡単に自己紹介すると、Android向けのSNS専用ブラウザ*1を作って(主に広告収入で)生活しているフリーランスのおっさんです。おかげさまでフリーランスになって今月で丸2年が経ちました。
今回は Tizen 向けに Facebook 専用ブラウザを Android から移植した感想などをつらつらと書いていきたいと思います。無駄に長くなったのでさらっと流して読んでもらえればw
今からおよそ1ヶ月前、それまで作っていたアプリ(TwitterクライアントTwitPane)がひとまず実用レベルになったので何か別のアプリを作ろうかと思っていたところで、ちょうど Tizen App Challenge の存在(と期限延長)を知りまして、にわかに(主にdisられて)知名度を上げているTizenプラットフォームに挑戦してみよう、と思ったのがきっかけでした。
Tizen App Challenge の期限は 2013/12/8(日) ということでほぼ1ヶ月ほどしかなかったわけで、Androidアプリを移植することにしました。
ターゲットとしては直近に作っていたのと同じTwitterクライアントも考えたんですが、どうせ世界中で山ほど量産されているであろうことは明らかなので、ここはあえてFacebookブラウザの移植にしました。
ちなみにFacebookのAPI(Facebook Graph API)はクソめんどくさいし、カジュアルに仕様変更するし、ドキュメントはすぐパーマリンク切れるし、このAPIをごにょごにょして専用ブラウザに仕上げるのは普通の精神の持ち主であれば容易に発狂する世界なので、・・・たぶん競合は少ないんじゃないかと思っています。APIの呼び方を実アプリのコードとして知ってるだけのアドバンテージはあるかと。。
Tizen には大きく(C++でコーディングする)Native Appと(HTML5でコーディングする)Web Appがあるわけですが、今回は期間が1ヶ月ほどしかないということで Web App にしました*2。
最初の数日は Tizen Web UI Builder ベースで作っていたんですが、HTMLとかjsをXMLから生成する分かりにくい仕様で、いえ別にそれ自体は C#/Visual Studio とかで自動生成のcsファイルと開発者が弄るcsファイルに分かれてるようなよくあるフレームワークではあるんですけど、無駄にHTMLとjsファイルが大量に作られるしUI Builderで作れるウィジェットしかおけないようなので制限が強すぎてやめました。
というわけで Tizen Web UI Framework で作ることにしました。これは jQuery Mobile (jQM) ベースの Tizen カスタマイズ版フレームワークみたいな感じですかね。某掲示板曰く「jQMを魔改造」されてるフレームワークなので色々と予想外の挙動に苦労しました。
Facebook の JavaScript API を使うんですが、Facebook の公式 JavaScript ライブラリは利用元HTMLファイルがWebサイト上にあることを要求する(そのドメイン名をFacebookの開発者コンソールで設定する)ので、実質的にlocalhostで動作する Tizen の Web App では利用できませんでした。
で、このあたりを参考にまぁ色々とごにょごにょして解決しました(別に面白くないので割愛します。。)
jQuery Mobile 自体の画面遷移を学ぶとなかなかよく出来ていて、この制御に苦労しました。
というのも、Facebookアプリではリスト系一覧画面を「NewsFeed」とか「○○さんのフィード一覧」とか「通知一覧」とかで使い回したいので、いわば「自画面遷移」が必要になるんですが、ページにパラメータを渡してバリエーションを作るのに一工夫必要でした。
pagebeforeshow イベントで次のような感じでパラメータを取得して画面の種別を判定する感じですね(このあとにさらにcurrentUrlParams.searchをパースする処理も必要です)。
onpagebeforeshow : function(e, d) { var currentUrl = $.mobile.activePage[0].baseURI; var currentUrlParams = $.mobile.path.parseUrl(currentUrl); ...
jQM の流儀なんだと思いますけど、こういうところだけでも丸1日ほど情報を探して試行錯誤してしまいました。
ほんと Tizen Web UI Framework の開発って、解決策が HTML5(JavaScript)/jQuery/jQuery Mobile/Tizen API のどのレイヤーになるのか調べるのが大変ですね。これに Type Script とか coffeescript とか、あるいは backbone.js のようなフレームワークを導入したらもっとレイヤーが深くなって、コーディング・デバッグが大変になると思うんですよね。でもまぁフレームワークってそういうもんなので、使いたい方は是非頑張ってくださいw
Facebookの(iOS/Android)公式アプリが採用して広まったと言われるサイドメニュー(サイドナビゲーション)ですので、今回私が作成するFacebookアプリでも採用することにしました。
どうやらサイドメニューは jQM 1.3 で panel としてサポートされているらしいんですが、Tizen 2.2 は jQM 1.2 ベースなので利用できませんでした。しかも Tizen 2.2.1 は jQM 1.3 になったぜ*3って書いてあるけど、エミュレータで実ファイル調べてみても jQM 1.2 だったからまじ残念です。魔改造の本領発揮ですねぇ。。
というわけでサイドメニューを扱うライブラリを探すことになったんですが、スマートフォン向けページでサイドメニューを実装する方法比較を参考に比較した結果、Sidrを採用しました。
でも、そのまま普通に導入・実装するとタッチではスクロールしてくれないので CSS の "-webkit-overflow-scrolling: touch" を記述したりしてなんとかエミュレータではスクロールできるようになりました。が、シミュレータではスクロールバーが出るだけでなんだか微妙な感じです。シミュレータでもリスト部分はタッチスクロールできるんですけどね。早く jQM 1.3 ベースになってくれればいいのにねー。
Tizenには物理キーとして「Menu」「Home」「Back」「Power」「Volume Up」「Volume Down」が用意されるようです。このうち、MenuキーとBackキーについては後から(今年7月リリースのTizen 2.2で)追加されたキーだからか(参考記事)、フレームワークとしてのサポートが正直雑ですw
言ってみれば「JavaScriptのイベントだけ用意しておくので実装は適当にやってね」というレベルです。
なので何も記述しないとMenuもBackも無反応です。バグですね。なにこれっていう。
で、Menuキー押したらサイドメニュー出したり、Backキー押したらちゃんと前の画面に戻ったりする処理をコツコツ書きました。jQMの画面遷移制御がめんどくさかったです。
var commonBackLogic = function(e) { try { if ($.mobile.urlHistory.activeIndex <= 0) { // if first page, terminate app window.tizen.application.getCurrentApplication().exit(); } else { // move previous page $.mobile.urlHistory.activeIndex -= 1; $.mobile.urlHistory.clearForward(); window.history.back(); } } catch (ex) { window.tizen.application.getCurrentApplication().exit(); } }; ... /** * hwkey */ onTizenhwkey : function(e) { var keyName = e.originalEvent.keyName; if (keyName === "menu") { var page = $(".ui-page-active"); page.find("#footerMenuButon").click(); } if (keyName === "back") { // sidr開いていたら閉じる if (main_page.sideMenuOpen) { $.sidr('close', 'sidr'); return; } commonBackLogic(e); } },
Tizen の記事を見るとよく出てくる Dynamic Box (Dropboxみたいだよねw) についても対応してみました。
Androidのウィジェット、WindowsPhoneのタイルのような感じですかね。普段はボックス型のアイコン(上記画面の上側の四角い部分)で、サイズを変更できたり、素早く下方向にスライドさせると詳細情報が表示される(上記画面の下側)ような UI です。
アプリとしては「ボックス」と「詳細情報(ドロップビュー)」を個別のHTMLとして作る感じで、アプリ本体とPreferenceやファイルなどで連携するようにしてみました。
某記事曰く、TizenのホームがDynamic Box対応になるらしいんですが、そんなホームアプリはSDKに存在しないので実機でどうなるのかすごく楽しみです。
まだ世界中で一台も商用端末が存在しないのになぜかストアが存在します。そしてTizen App Challengeはこのストアの審査に合格することが応募条件になっています。端末リリース時点でのアプリを充実させることを目的にしているわけですね。
審査はわりとゆるめですが、これまで8回申請して(同一アプリのアップデートが7回あったということ)、結果2回rejectされました。その理由は「(通信できない/ログインできない場合に)動作しない」「スクリーンショットに不適切な文言がある」というものでした。修正するのは簡単ですが、全部英語で説明しなきゃいけないのが若干めんどくさかったですね。Apple の App Store とは比べものにならないんでしょうけどw
審査自体は最短で当日〜数日(最長でも3営業日)で通りました。
ちまたの噂では docomo が Tizen 端末 SC-03F を発売するらしい ので楽しみではあるんですが、エミュレータを触った限りではどこが使いやすいのかさっぱり分からないし、開発者としてもユーザーとしても正直ほとんど面白さを感じていません。むしろ商用端末でどれだけ進化するのか楽しみです。
iOSやAndroidは既に数年前からレッドオーシャンなので、開発者としてはブルーオーシャンに向かうのは当然なんですが、Tizenはむしろ「海かと思ったら湖だった」くらいの感覚だと思っています。サロマ湖のように海につながっているといいんですけどもー。
あと、「画面遷移とか〜」にも少し書きましたが、フレームワークの階層が深いので慣れるまでは案外大変だと思います。「Tizenアプリ開発はHTML5ベースだから簡単です」なんていう言葉にはだまされないようにしましょう。Chrome由来のデバッグツールは確かに強力ですし、HTML5への準拠度もすごく高いので開発効率が高いのは間違いないですが、「Web開発に不慣れなiOS/Androidアプリ開発者」にとってはただただ迷子になるだけの辛い道のりです。ネットの情報も少ないですし。でもその分チャンスなのかもしれませんけどー?
ちなみに開発時には下記の本を参考にしました。
今回の開発では↓の本を一番参考にしましたが、$.mobile.activePage について書いてなくてすごく苦労したので↑の本がおすすめです。
Tizen端末が発売されるのを楽しみにしつつ、それまでwktkしながらアプリをアップデートしていきたいと思います。