[Titanium]WebViewの遷移先を横取りする

最近まーったくTiを触れていないのですが。書くと役立ちそうな話題を見かけたのでちょっとだけ。

WebViewを利用したアプリケーションの場合によくあるのが、
特定のドメイン(URL)じゃないページへ遷移する場合は、通常のブラウザアプリ(Safari等)で開く
という要件です。
Ti.UI.WebView で、遷移先(遷移しようとしている)URLを知りたい ~ ‘beforeload’ イベントで url が反映されない件 #titaniumjp #titanium – harukazepcの日記

“[Titanium]WebViewの遷移先を横取りする” の続きを読む

【Titanium Advent Calendar 2011:二日目】evalJSの恐怖

【はじめに】

この記事は、@astronaughtsさん企画の「Titanium Advent Calendar 2011」向けに書いています。
@astronaughtsさんは、この企画もそうですけど、それ以外にも関西で最大規模のTitaniumイベントTi.Developers.meetingの主催者でもあります。最初はどうしようかと思うくらいしょぼかったw Ti.Devs.me、諦めずに開催を繰り返して大きなイベントに育て上げた@astronaughtsに、個人的今年のTitaniumMVPを送りたいです。


さて、そんなわけでTitaniumの話題を一つ。Titaniumでは、アプリ内でブラウザが開くwebViewという仕組みを使うことができます。
これを使うと、アプリ内でWEBページを見てもらうことができるので、Titanium以外でもよく使われている仕組みです。これ、意外と怖いということはご存知ですか?

例えば簡単なアプリを用意してみましょう。このアプリは、起動すると、モバイラーズオアシスというサイトをwebviewで開きます。

mo.png
俺ブラウザ — Gist

このアプリの最後に、ちょっとスパイスをかけてみます。

mo1.png

上野駅が蒲田駅に変わってしまいました。これで、モバイラーズオアシスの中の人は、「蒲田駅を検索したら違う位置が表示された」という謎のバグ報告に悩まされることになります。クックック。永久に悩み続けるがいい…

ご自分のアプリのWebViewに上記を仕掛けるとか、絶対やめてください。やめろってば!
冗談はさておき、技術的にこういうことが可能であることは頭においておく必要があります。今回は上野が蒲田になる程度ですみましたが、ニュースサイトの内容を書き換えられたら?ログインしたときにユーザー名とパスワードを他のサイトに送信する仕組みが入っていたら?
webViewとブラウザを同一視していると、あっと驚く手品に巻き込まれてしまうかもしれません・・・

逆に、この手法をうまく使えば、スマートフォンに最適化されていないHTMLに別のCSSを適用して要素を大きく表示させたり、サイドバーを隠してスマートフォン向けのページに見せるようなこともできるかも。
…できるかもしれないのですけど、実際は結構大変です。この記事を書くために色々試したのですけど、evalJSしたJSコードをデバッグする手段が無いので、泣きそうでした。
ちょっと複雑なJSを書くと、なぜか処理が行われなくて途方にくれます。いい思いつきだと思ったんだけどなぁ。

【おわりに】

明日は@rakiさんかな。よろしくおねがいします〜。

[PHPMatsuri]Titanium大賞をいただきました

jhmr.gif

PHPな人が集まって一晩中開発を行うイベントPHP祭りに行って来ました。

「mogyaさんPHP祭りは来ないの?」
「最近PHPは全然書いてないのでノーチェックですねぇ。」
増井さんを呼んでTitaniumの話をしてもらうよ」
「今申し込みました(即答)」

というような経緯です。

実際行ってみたら、

masuidrive「この中で、Titaniumをご存知のかた?」(挙手)
masuidrive「Titaniumでプログラムを書いたことがある方」(挙手)
masuidrive「Titaniumでアプリを作ってリリースしたことのある方」(挙手)
masuidrive「今日は初心者向けなので、今挙手された方が聞くような内容はありませんw」

って言われました。そりゃまあそうですよね。

ハッカソンでは、電源検索の無料版「電源検索Lite」を開発して「Titanium大賞」をいただきました。

6253918541_5b2d940be1_o.jpg

そういうわけで、「電源検索Lite」for iPhoneは今Appleで審査中なので、審査が通ればAppStoreに登場する予定ですので、楽しみにお待ちくださいませ。
ちなみに、待ち切れない方は、電源がないお店も検索できる有料版がすでにAppStoreに出ております。

[Titanium] iPhoneでAdMaker広告を掲載

Titaniumで作ったiPhoneアプリに広告を出す場合、モジュールが簡単に手に入るAdMobが人気ですが、AdMaker(MediaAd)は使えないの?という声も多いみたいです。やってみたら簡単に出来たので、やり方をまとめてみます。

モジュールを使う

下記を落としてきます。

tryden/TiAdMaker – GitHub

titanium.xcconfigを開くと、TitaniumSDKのバージョンが定義されているので、これを自分の好みのものに書き換えます。1.6.1はちょっと微妙ですね。
titanium.xcconfig.png

で、build.pyを走らせるとモジュールが出来上がります。
build.png
build2.png

出来上がったモジュールを解凍して、新しいプロジェクトにこんな感じで配置。
module-1.png

example/app.jsにサンプルがあるので、まずはこれを動かしてみるのがいいんじゃないかと思います。

app.js-1.png

AD_URL、SITE_ID、ZONE_IDはAdMakerでメディアを作るともらえます。
medibaad-1.png

というわけで起動してみるとこんな感じ。
sample1.png

めでたしめでたし。

webviewを使う方法

 ちなみに、AdMakerの公式サイトでは、こんなふうに案内されています。

TitaniumへSDKを実装できません。どうすればいいですか?
SDKでの対応はしておりません。
Web Viewを作って頂き、そこにJavaScriptタグを実装して頂くことで表示して頂くことも可能です。
(よくあるご質問|スマートフォン広告なら「mediba ad」|iPhone、Androidアプリ・サイト広告)

JavaScriptと空っぽのbodyタグを書いたHTMLを用意してwebviewで開いたところ、広告はちゃんと表示されたのですけど、クリックしたあとの広告もwebviewの中で開いて、どうしてくれようかという感じになりました(当たり前ですね)。
webviewのイベントをハンドリングしてあれこれという手も考えられるのですが、あんまりやると広告に手を入れているように見えてしまうことが懸念されます。モジュールが動くのだったら、そのほうがいいんじゃないかな、と思います。

P.S: Android用はこちら。
titanium の AdMaker モジュール作ってみました(Android用) #titaniumjp – harukazepcの日記

[Titanium]CFBundleVersion must be no longer than 18 charactoers

個人的なポリシーで、アプリケーションのバージョン番号は、1.0, 1.1, 2.0とかじゃなくて、20110923, 20110925…っていうふうに年月日でつけることにしています。
どこでマイナーバージョンを上げてどこでメジャーバージョンを上げるかとか悩んでも仕方ないし、ユーザーさんにとってはどっちが新しいかさえ分かればOKなんだから、無理に数字に丸める理由はないよね。

というような経緯で俺ポリシーを採用していたら、えらい目にあいました。

理由は知らないんだけど、Titanium MobileはInfo.plistに書いてあるBundleVersionの後ろに、タイムスタンプをくっつけてしまいます。例えばInfo.plistに「1.0」と書いた場合、実際のビルドに使用されるCFBundleVersionは「1.0.1316956026」という具合に。
普通の人はバージョンなんてせいぜい5文字だから、
日付時刻をつけても弊害はなかったのだけれど、年月日方式だと、「20110925.1316956026」となってしまいます。実はバージョン番号には18桁までという制限があるので、これだとCode SignをするときのVelificationでエラーになってしまうのです。

厄介なことに、このアプリの旧バージョンはXCodeで開発していたので、年月日方式ですでにリリースしてしまっています。
しょうがないので、「3.0」にしてみたんだけど、これも「The key CFBundleVersion in the Info.plist file must contain a higher version than that of the previously uploaded version.」ということでどうにもならなくて泣きそうに。Adhoc Buildまで無事通って、最後の最後に発覚するので心理的ダメージがでかいです。

そういうわけで、このTitanium Mobileの余計な処理を止める方法。
builder.py ( /Library/Application Support/Titanium/mobilesdk/osx/#{TITANIUM_SDK_VERSION}/iphone/ )をひらいて、この辺をコメントアウトする。

僕から見たら余計な処理だったけど、書いてあるからには必要な理由があったのだろうから、普通の人はまねしない方がいいと思う。
バージョン番号が長くなって困った方だけ、自己責任でどうぞ。

おまけ:Distribution Buildのハマリどころ

 iPhoneアプリの開発は、エミュレーターで動いて、AdHocビルドも動いているのに、最後の最後でリリースできない!って苦労することが多い気がする。
自分が今回はまった点と解決策。

  • Distribution Buildした後、Validateするとすっごい長いエラーダイアログが出る
    →キャプチャしておくのを忘れたんだけど、ほぼ画面いっぱいのエラーダイアログ。長すぎて結局何がエラーなのか全然分からなかったんだけど、ダイアログの上でcommand+Cを押すと全文がコピーできるので、エディタに貼り付ければ内容を見ることが出来る。
  • 「Icon specified in the Info.plist not found under the top level app wrapper: icon.png Unable to verify icon dimensions, no icon found」
    →可能性1:info.plistに書いてあるアイコンファイルと実際においてあるアイコンファイルの名前が違う。大文字小文字にも注意。
    →可能性2:アイコンファイルが8bit pngになっている。24bit pngじゃないとダメらしいです。
  • 「a sealed resource is missing or invalid」
    →Resourcesに余計なファイルがあると起きるらしい。.gitとか.gitignoreとかそのへんをひと通り削除したら出なくなった
  • 「CFBundleVersion must be no longer than 18 charactoers」
    →上に書いたとおり。「バージョン番号は18文字以下でないといけません」。

CodeSignとかMobileProvisioningになってしまえば、もはやTitaniumMobileであることはあまり関係が無いので、「エラー文字列 iPhone」でググるのが王道のような気がしました。

[titanium]TKAnimationSampleはTitanium開発者必見のアニメーションサンプル集

Ti.Developers.meeting vol 0.3 で、MogSnapのコバヤシトールさんに、アニメーションについてお話していただきました。

その際の説明用サンプルとして掲示されたTKAnimationSampleがとても素晴らしかったのでご紹介。

toru0325/TKAnimationSample – GitHub

TKAnimationSample1.png
KitchenSinkみたいに、複数のサンプルが見られるようになっています。

TKAnimationSample2.png
HelloWorld.js。静止画見ても何のことだか分からないと思いますが、HelloWorldが下から飛び出してくるサンプルです。

TKAnimationSample4.png
buttons.js。ボタンが出現するサンプル。よりかっこいいbuttons_with_scale.jsというのもあります。

TKAnimationSample5.png
赤いボールが複雑な軌跡を描いて飛び回るredbox.js。「Hint」ボタンを押すことで、どういうふうに実現されているかを見ることが出来ます。

TKAnimationSample6.png
AndroidやiPadのように画面上にポップアップを出現させるInfo_view.js。iPhoneではあまりやらないことになってますが、実現させたい人はたくさんいると思うので、そういう方はこのサンプルを参考にすると良いと思います。

ゲームやかわいいアプリケーションにアニメーションが必須なのはいうまでもないですが、情報系のアプリケーションでも、ちょっとアニメーションを利かせておくことで、
ユーザーさんの目線を誘導することが出来るのでとても役に立ちます。
APIリファレンスを見て実装してもなかなか上手く動かないのですけど、TKAnimationSampleで動いているサンプルをみて実装するのなら簡単に実装できますよね。
自分はTKAnimationSampleを見て30分くらいで、今作っているアプリにアニメーションを追加することが出来ました。
とても勉強になるので、ぜひさわってみてくださいませ。

[ti.devs.me] window.urlを使わないプログラミング

明日16日のTi.Developers.meeting vol 0.3 in Kyotoで、「window.urlを使わないプログラミング」というテーマでお話させていただきました。

Ti.Developers.meeting.001.jpg
Ti.Developers.meeting.002.jpg
Ti.Developers.meeting.003.jpg
Ti.Developers.meeting.004.jpg
Ti.Developers.meeting.005.jpg
Ti.Developers.meeting.006.jpg
Ti.Developers.meeting.007.jpg
Ti.Developers.meeting.008.jpg
Ti.Developers.meeting.009.jpg
Ti.Developers.meeting.010.jpg
Ti.Developers.meeting.011.jpg
Ti.Developers.meeting.012.jpg
Ti.Developers.meeting.013.jpg
Ti.Developers.meeting.014.jpg
Ti.Developers.meeting.015.jpg
Ti.Developers.meeting.016.jpg
Ti.Developers.meeting.017.jpg
Ti.Developers.meeting.018.jpg
Ti.Developers.meeting.019.jpg
Ti.Developers.meeting.020.jpg
Ti.Developers.meeting.021.jpg
Ti.Developers.meeting.022.jpg
Ti.Developers.meeting.023.jpg
Ti.Developers.meeting.024.jpg
Ti.Developers.meeting.025.jpg
Ti.Developers.meeting.026.jpg
Ti.Developers.meeting.027.jpg
Ti.Developers.meeting.028.jpg
Ti.Developers.meeting.029.jpg
Ti.Developers.meeting.030.jpg
Ti.Developers.meeting.031.jpg
Ti.Developers.meeting.032.jpg
Ti.Developers.meeting.033.jpg
Ti.Developers.meeting.034.jpg
Ti.Developers.meeting.035.jpg
Ti.Developers.meeting.036.jpg
Ti.Developers.meeting.037.jpg
Ti.Developers.meeting.038.jpg
Ti.Developers.meeting.039.jpg
Ti.Developers.meeting.040.jpg
Ti.Developers.meeting.041.jpg
Ti.Developers.meeting.042.jpg
Ti.Developers.meeting.043.jpg
Ti.Developers.meeting.044.jpg
Ti.Developers.meeting.045.jpg
Ti.Developers.meeting.046.jpg
Ti.Developers.meeting.047.jpg
Ti.Developers.meeting.048.jpg
Ti.Developers.meeting.049.jpg
Ti.Developers.meeting.050.jpg
Ti.Developers.meeting.051.jpg
Ti.Developers.meeting.052.jpg
Ti.Developers.meeting.053.jpg
Ti.Developers.meeting.054.jpg
Ti.Developers.meeting.055.jpg
Ti.Developers.meeting.056.jpg
Ti.Developers.meeting.057.jpg
Ti.Developers.meeting.058.jpg
Ti.Developers.meeting.059.jpg
Ti.Developers.meeting.060.jpg
Ti.Developers.meeting.061.jpg
Ti.Developers.meeting.062.jpg
Ti.Developers.meeting.063.jpg

コンテキストを超えた値の共有[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!