2012年1月31日火曜日

(続)モバイルアプリ開発、何使う?

前回のエントリでモバイルアプリ開発に何を使うか書いたばかりだが、非常に参考になるブログがあったので、紹介。

どうしてTitanium Mobileなの?


て、3日前に書かれた記事ですね。
みんな同じような悩みを抱えつつ、自分なりの答えを探しているんですね~。

ぼかぁ、どれもこれもまだ触ってないので、オモテから見える部分でしか評価できないんで非常に参考になりました。

モバイルアプリ開発、何使う?

PCクライアント版PushIt!も完成してないのになんだが、モバイルアプリ(正確にはスマホ向けというべきか)にも手を出したい今日この頃。

さて、モバイルアプリと言えば、昨今はいろいろと作り方があるので、最初を間違えると後で不良債権を抱えてしまうことになり、選び方に慎重になってしまう。

ちょっと比較をしてみた。ターゲットはiOSとAndroidだ。


  • 1. ネイティブアプリ
    言わずと知れたObjective-C(iOS)とJava(Android)である。実行速度と「オワコン」にならなさ加減では間違いない選択。しかし、なるべく手間をかけずに両方対応したいならまず外すべき選択肢。Push It!のようなツール系アプリなら実行速度をあまり気にしないので忘れても結構。

  • 2. Unity
    Mono(Windowsの.NETフレームワークのオープンソース版)を使った開発・実行環境。事前にネイティブコンパイルするので、実行速度はネイティブ並み(Javascriptでも開発できるらしいが、それもコンパイルするのかは不明)を確保しつつ、サポートプラットフォームが半端無い。ネイティブ形式にパッケージングされるのでアプリストアで売れる
    基本、ゲーム向けのフレームワークなので、ライトな用途には重量級すぎるかも?使ってみないとなんとも言えないが。移植性はわからん。

  • 3. HTML+CSS+Javascript
    言わずと知れた。アプリっぽくするにはjQuery Mobileなんかを使いつつ、キャッシュやローカルストレージを駆使してローカルでも動くようにしないとね。
    実行速度的にはまあそれなり。ツール用途で、かつデバイスの機能をフル活用しなくていいならありな選択肢。デバイス特化な機能を使わないなら移植性も高い。
    iOS向けにAppStoreで売って小遣い稼ぎしたいならなし

  • 4. PhoneGap
    基本的に3と同じだが、ネイティブ形式にパッケージングされるのでアプリストアで売れる
    デバイス機能へのブリッジもある程度用意されているので、そこそこ凝ったアプリもイケる。

  • 5. Titanium Mobile
    1と同じことを言語にJavascriptを使う、といったら良いだろうか。同じくJavascriptを使う3,4との違いはViewの部分(つまり見た目)もJavascriptで構築するところ。
    当然、ネイティブ形式にパッケージングされるのでアプリストアで売れる
    Javascriptがネイティブコードにコンパイルされるなんて情報もあるが定かではないので、実行速度は不明。
    移植性に関しても良く分からないが、ViewとI/Oをうまく切り出せれば大部分は流用できるだろう。
    どんだけ流行るか不明。

  • 6. Adobe AIR (for Mobile)
    AIRランタイムを使ったアプリをネイティブ形式にパッケージングするもの。
    思想的には2や5に近い。Flash(Flex)開発者にとっては取っ付きやすいが、そのFlashがモバイル向けから手を引いたので、衰退の予感。HTML+Javascriptでも開発できるけど、その場合は3,4でもいいわけだし。
    PCとのマルチデバイス展開もやりやすいといえばそうだが、PC向けとは(ある程度コードは共有できるけど)別物だと思った方が良い。

個人的には、実行速度的にはどれでも満足できる用途なので良しとして、1はマルチデバイス展開の点でナシ、2は重量級すぎてナシ、6はオワコンの予感でナシ、3やるくらいなら4の方が楽できる(し売れる。実際売れるかどうかは別だが)のでナシということで、残るは4,5になる。

で実際5ってどうなんですかねえ。開発者ついてるんですかねえ。
4は時々ニュースになるし、PhoneGapそのものの魅力ではないけど、UI周りではjQuery Mobileが巨大なコミュニティを持っているおかげで凝ったViewも作りやすそうなので、今後も有望なんじゃないかと思うんだけど、どうかな。

2012年1月28日土曜日

Aptana Studio with Pleiades on MacOSX

Push It!のサーバ側は、俗にいうGAE/Pであり、つまりPythonなのである。
で、Pythonの開発環境として有名なものにはPyDev(Eclipseのプラグイン)というものがある。
PyDevはもちろんただで使えるのだが、基本、Aptanaという会社が作っていて(多分)、AptanaはEclipseベースの開発環境であるAptana Studio(これもただ)を配布しており、当然その中にはPyDevも入っている(だけでなくスクリプト系Web開発環境のほぼすべてが揃っていると言っても過言ではないくらいてんこ盛りである)。

さて、そのAptana Studio、Eclipseベースなので当然Javaであり、当然Macでも動く。
Mac用インストーラも配布されているので楽チンなのだが、残念ながら日本語化されていない。

Eclipseを日本語化するには有志の皆さんが作っているPleiadesというプラグインがあり、(Windows版なら)Eclipse込みのパッケージも配布されている、が、前述の通り自分は
「Macに」
「Aptana Studioを」
入れたのであり、Eclipseは既に存在しているところにPleiadesを入れたいのだ、わたしゃ。

Pleiadesは単なるプラグインではなく、ものすごく乱暴に言うと、
「Eclipseのテキスト表示をインターセプトして、その場で翻訳して日本語で表示しちまうぞ、こら!」
という仕組みであるらしく、plugins & featuresフォルダにファイルを突っ込むだけでは足りず、インターセプトするために起動オプションに仕込みが必要になる。

で、前置きが長くなったが、起動オプションなんである。
Pleiadesの配布パッケージには優しい(易しくはない・・・)READMEがついているんだけど、Eclipseの起動オプション設定として、世界で70億人くらいが使っているであろうeclipse.iniがAptana Studioには、ない!

どーすりゃいいんすか〜、まあ、メニュー等が日本語でなくてもソースに日本語が使えないわけではないのだし、なんとかなるけど・・・と思いながらも諦めきれず探していたら、ありました。別の名前で。

その者の名は、

/Applications/Aptana Studio 3/AptanaStudio3.app/Contents/MacOS/AptanaStudio3.ini

である。

第一のトラップは「AptanaStudio3.app」であり、MacのFinderでは通常「.appなフォルダ」は実行ファイルに見える。が、実体は特殊なフォルダなのであり、それに気がつかなかったというか、知ってたけどその中まで探さなかったこと。

第二のトラップはeclipse.iniではなく、AptanaStudio3.iniであること。まあ、こちらは第一のトラップがわかれば容易くわかる、のだが、それに気がつかない間、「.appフォルダ」を特別扱いしないツールであるコンソールから、一生懸命

find "/Applications/Aptana Studio 3" -name eclipse.ini

しても見つからなかったのでプチトラップである。
恐るべしMac、そしてAptana Studio・・・の巻。

2012年1月18日水曜日

FlashDevelop4系正式リリース

今か今かと待ちわびたFlashDevelopの4がいつの間にか(クリスマスのちょい前)リリースされていたらしい。(待ちわびてる割に見逃すってどういうこと・・・)

べらぼうに増えた機能(しかし配布サイズはたったの16MBだ!)を使う日は当分先なんだろうな・・・。

目先の嬉しさといえば、標準で組み込まれるAIR/FLEX SDKのバージョンが最新化されたことだろうか。

FlashDevelop3でもSDKだけAdobeから落としてきて差し替えることもできるこのあたりにお世話になりました)のだが、しかし、
難易度が超絶高い!
というのは言い過ぎにしろ、標準で入ってくれているのは非常にありがたい。

新機能としては、AndroidSDKが不要な、(AIRによる)Androidアプリ開発ができるとかあるみたい。素敵すぎてヨダレが出そう。

Eclipseもいいけど、Flex/ActionScript/AIRの開発は絶対こちら!おすすめ!本も買って読むべし!でもやっぱりFlashBuilder(Eclipseベースだったりする)欲しい!

2011年11月30日水曜日

Herokuに浮気・・・が始まらない

GAEの新料金体系で、インスタンス課金がどうしても気に入らない(※)ため、Herokuに乗り換えようかと画策中。


だってね、インスタンスはほぼ1日中1個(時々0個か2個)上がってるから、インスタンス使用時間は約24H/Dayなんですが、CPU時間で見ると0.1%くらいしか使ってないわけですよ。それでも継続的にリクエストが来るからインスタンスが上がりっぱなだけで。
CPU使ってないんだからもったいないなあ、、、というのが正直なところ。まあ、メモリは食ってますけどね。

なんだけど、Herokuにアプリを登録するのは、rubyで動くherokuコマンドをインストールする必要があり、gitも必要です。あと、サンプルを動かすためにrailsなんかも必要で、gemから入れようとしたら失敗するし(Windowsだから、という原因もある)、どうすりゃいいんだわたしゃ、と思っている次第。
まあ、railsはgemで入れんでも良いような気がするが、誰か楽なHerokuの始め方を教えてくれー。

ただ、GAEの新料金のネック(Push It!における)はもう一つ、Channel数の制限があるんですが、
Herokuにしたところで、WebSocket(GAEだとChannelにあたる。Channelの方が対応環境が多いが)は標準では対応してなくて、Pusherというアドオンを入れると使えるんだけど、無料だと20connectionまでって、それGAEのChannel数制限と大差ないから!ということに気づく。
無料だと・・・どこ行ってもキツイね・・・。そらそうなんだが。

2011年11月19日土曜日

Datastoreのunittest(Python)

HRDネタが続いてますが、GAEの公式ドキュメントに、
http://code.google.com/intl/en/appengine/docs/python/tools/localunittesting.html#Writing_HRD_Datastore_Tests
こんな記事があるのを見つけました。

unittestのための記事なんですが、Eventual Consistencyな状態を、指定した条件で疑似れる模様。まだ使ってませんが。

あら素敵じゃない。HRDそのものはxx(←自粛)ですが・・・。
でもな〜、ドキュメントこれだけ?リファレンスは?ここに書いてあることが全部?
う〜ん・・・。

2011年11月10日木曜日

High Replication Datastoreの扱いに困る話

第一章 はじめに


前回のエントリで書いたように、GAEのPython2.7で使えるDatastoreは、High Replication Datastore(HRD)というやつ一択で、こいつの扱いが難しいのに困っている。


具体的には、クエリの整合性が担保されないということなのだそうな。

・キーを使ったアクセスは「問題なし」
・祖先クエリ(Entityの親子関係を使ったクエリ)は「問題なし」
・その他のクエリは「過去の状態に基づく結果が返る可能性がある」


なので強い整合性を必要とする場合、memcacheやら何やらを駆使して、解決せよ、というのがGoogle始め、各人の御宣託なのであるが、しかし、memcacheも消えることがあるのだし、どうしようか。というお題である。

第二章 解決策

そこで考えたのが、
  • Datastoreへのアクセスをラッパーするクラスを作って、書き込み時はmemcacheにも必ず書き込む。
  • クエリは、ラッパーを経由することで、Datastoreに対する検索結果とmemcacheのデータをマージして返す。
  • クエリもパターン化されているなら、クエリの結果もキャッシュしておく。
  • と、そこまでやってもmemcacheは消えることもあるので、Datastore操作ログをDatastoreに残す。ログは全数にアクセスできないといけないので、Key名はプログラム的に推定可能なものを採用する。
ということ。

第三章 問題点

よし。ここまでやりゃ大丈夫か。いや、トランザクションとか使うともっとややこしいことになるが。

ただ、機能的には大丈夫なんだが、問題もある。
  • 「Datastoreに対する検索結果とmemcacheのデータをマージ」するコスト(CPU時間)がバカにならない気がする。
  • 特にmemcacheデータが増えてきた場合。
  • なので、memcacheを定期的に捨てないといけないのだが、Datastoreへのクエリがいつになったら整合性が取れるのか分からないので、捨て時がわからない。
  • あるクエリの実行結果がmemcacheと一致するなら「そのクエリに関しては」整合性が取れたと言えるのだろうが、別のクエリでも一致するとは限らない(と思う)ので完全に整合性が取れたと言い切れるタイミングが図れない。
  • Datastore操作ログもmemcacheと同様に捨て時がわからない。
ふ~む、困ったね・・・。

第四章 HRDで整合が取れるまでの時間とは


で、実際HRDで整合性取れるのってどのくらいかかんのよ、ってことで実験してみたよ。
  • Datastoreにput()する
  • 直後に「put()したデータだけ」がひっかかるはずのクエリを投げる
  • 引っ掛かった件数が1なら整合、それ以外なら不整合と判定する
結果:必ず一件取れた。おいおい・・・、優秀じゃねーか。

ん~、データが軽すぎるのかも知れない。プロパティ数が数個かつエンティティ数も100件程度じゃ、あっという間にインデックスが構築されてしまう模様。

じゃ、プロパティを26個まで増やし、エンティティ数も1000件程度の状態まで持って行ったらどうか。

結果:数百回試して1回だけ0件となった。

なるほどね・・・。
スクリプト言語であるPythonごときの処理速度では、インデックス構築完了より先にクエリは投げられんよ、と、そういうことか?

てーことは、何?上に書いたような対策は杞憂なの?やりすぎなの?
でもさー、保証されてないんだから考えちゃうよね、そりゃ。

第五章 終幕


とかって実験しているうちに、Over Quotaとなった。。。

新料金体系では、無料枠は
Datastore Write Operations : 0.05 Million Ops
となっているので、Write Opsは5万回まで。

Write Opsってput()とdelete()の回数ですか?って甘かった。
put()/delete()の際のインデックスの更新もWrite Opsに含まれるんだってよ、奥さん!

インデックスは、Keyと、プロパティ1個1個に対して昇順と降順のインデックスが作られるので、
・データそのもの(1)
・Key用インデックス(1)
・プロパティの昇順、降順(プロパティ数 x 2)
だけのWrite Opsが発生するんだって!一回のput()で!

上記の実験では26個のプロパティを用意したので、一回当たり 1 + 1 + 26 * 2=54 Ops

5万 ÷ 54 = 約1000

そう。たった1000回(未満)のput()でOver Quotaなのであった。
なーんーだーよー。

ろくろく実験もできねーじゃねーか。

なんかもー、こんな対策考えてる時点でベンダーロックインされまくってる弊害がありありだし、別に安くもなくなっちゃったし、もうGAEやめちゃおっかな、とか思うんだが・・・。