伊藤清徳の垂直落下式ムーンサルトプレス

PerlとかPHPとかMySQLとか...がんばっても8割だ。

Category: iPhone

iPhoneで簡単にバーコードリーダーを作る方法

今回はiPhoneで簡単にバーコードリーダーを
HTMLベースで作成する方法をメモ。
 
iPad iPhone iPodTouchではiOS4から、
URIベースでできたアプリケーション間メッセージングプロトコルの仕組みが導入されました。

これに合わせてpic2shopというバーコードリーダーアプリケーションに、
このプロトコルに合わせたAPIが導入され、
pic2shopを、バーコードリーダーの端末として扱えるようになっています。
 
注意点として、
pic2shopは、QRコードを始めとする二次元コードには対応していません。


iOSのメッセージングプロトコルは

アプリケーション://API関数(?=パラメータ)

という非常にわかりやすいURL構造でできています。
HTMLアプリケーションを作る場合は、
そのままこのURIを aタグのhrefに設定していまえば、
指定したアプリケーションが起動します。


pic2shopのAPIでは、
 

pic2shop://scan?callback=コールバック

 
というAPIを指定しておけば、リンクをクリックしたときに、
バーコードスキャナが起動する仕組みです。

コールバックの部分には、
同じくURIメッセージングプロトコルの書式をURIを記述(URLエンコードをします)すれば、
スキャン後、今度は、そちらのメッセージングが実行されます。

読み取った結果は「EAN」という文字列を、
コールバックに埋め込んでおけば、
読み込んだ結果に置き換えてコールバックを実行してくれます。

たとえば、

<a href="pic2shop://scan?callback=http%3a%2f%2fhogehoge%2ecom%2fhogetest%2ephp%3fcode%3dEAN">
スキャン
</a>

こんなHTMLを作って、Safariでこのページをロードして、
「スキャン」というリンクをクリックすると、
pic2shopのスキャナが起動。
読み込みが完了すると、
「http://hogehoge.com/hogetest.php?code=読み込み結果」
というページがSafariで表示されます。

このURLをJSなりPHPなりでパースして
読み取り結果をキーとして、
DBからデータを引っ張るなどすれば、
結構複雑なアプリケーションも、
無料ツールで しかも HTMLベースで構築可能になります。

このメッセージングの機能はobjective-Cからも利用可能なようで、
pic2shopのマニュアルに詳細があります。

iOS端末でこういった機能が簡単に作れれば、
エンターテイメントな面の端末としてでだけでなく、
かなり実務的というアプリケーションの安価開発の可能性も
広がるのではないでしょうか。

久々にPhoneGap

初代iPodTouchからあいぽん4に大幅ジャンプアップした!
もうすぐアンドロイドOSのパッドも届く!
ってことで某WEB系勉強会のLTのネタにPhoneGapを話してみたいと思う。
 
PhoneGapとは、HTML+JSでiPhoneやiPad、Andoroidのネイティブアプリケーションをつくるためのフレームワークです。
公式サイトはこちら
 


 
私が使っていた1年前は、組み込み大変。
思ったように動かない。
実装されている関数が少ない。
など、プログラマ的にはかなり遊べるフレームワークではありましたが、
たとえばプログラムに疎いWEBクリエータが使ったりするのには、
かなりキツいフレームワークでした。
 
しかしながら、インストールは、インストーラーが整備され、
非常に簡単にインストールができるようになっています。
 
また、1年前に使っていた頃は、プロジェクトに組み込むのも大変でしたが、
現在はXcodeで…
 

 
プロジェクトを作成するときに、「PhoneGapTemplate」をクリックすれば、
自動的にPhoneGap用のプロジェクトが作られます。
なんか難しいファイルがたくさん並んでますけど、
 

 
WEBクリエーターならなんとなくどっかで見たことある「www」というフォルダが。。。
WEBサーバーの公開ディレクトリと同じです。
 
最初の話を思い出すと「HTMLとJSで作るiPhoneネイティブアプリ」ですよね?
つまり、このディレクトリの中にHTMLやJSや画像やCSSや..etc..を入れていけば、
ネイティブアプリケーションを作れるというわけです。
 
 
まぁ、あれです。
Objective-Cを使うよりかなりスピードは落ちますが、
プログラミングは疎いけど、
WEBクリエイティブなマインドを活かすにはいいフレームワークではないでしょうか?
 
今後、時間があれば、PhoneGapのAPIを紹介していければ、、、、いいなぁ、、、

iPhoneのタイマーがこまった

iPhoneでNSTimerでタイマー処理を行うアプリを作っている
http://d.hatena.ne.jp/moto_maka/20081210/1228855024
↑この辺が役に立った。

実際に動かしてみると、1/100秒程度はうまくいくのだが、ミリ秒単位で処理するともはやアウト。ここまでは上記のURL内の記述どおり。では、と思い色々タイマーの中で動作を記述すると、実際には1/100秒でもうまく動かない。かなり「揺れ」がある(T_T)

調べるとNSTimerはハード的な割り込みができず、信頼できないタイマーだそうだ。それってタイマーって言ってよいのか??

スレッドをつかって云々も結構問題があるみたい。やるとすれば、信頼できないタイマーを起動しっぱなしにして、NSTimeIvervalで時間計測しながらやっていくしかないかな。。。うがぁ。。。

PhoneGapでJavascriptAPI追加方法概要編

このところは、PhoneGapというHTML+JavascriptでiPhoneアプリを作れるものにハマっています。

HTMLでGUIを組み上げていくわけですが、
画像などを自分で用意し、CSSや<img>タグを駆使すれば、
リッチなGUIが簡単に完成します。

Javascriptで実装されている機能はほぼ完璧に使えますので、
煩わしいObjective-Cのソースを書くという作業は、相当数少なくなります。

速度はどうかなと思ったんですが、

SafariはPCの世界でも評判の速度。
そのパワーを借りるわけですから、
心配するほど遅いことはありません。

驚くべきライブラリです。
この前の記事にも書いていますが、
MITライセンスってとこがまたいいですよね!

、、、とまぁここまで散々褒めちぎっていたわけですが、
たとえばファイルの入出力などは、Javascriptの範疇じゃないので、
Objective-Cの力を借りたくなるのです。

さてどうしたものか、、、調べたところ、
PhoneGapのJavascriptAPIを拡張する方法が分かりましたので、書いておきます。
ある程度Objective-CとJavascriptの知識が必要ですので、
そのあたりは心してごらんください。

PhoneGapでは、JavascriptAPIを実行したとき、
gap.js(PhoneGapのJavascriptAPIファイル)が、

「gap:」を文頭につけたURLがリクエストされたものとしてWEBViewオブジェクトへリクエストし、
WEBViewは、受け取ったURLの頭が「gap:」だったら、
通常のURLリクエストとは別の動作(ここがAPIの実働部分)をするように構築されているようです。


PhoneGapにデフォルトで実装されている関数「Device.soundPlay()」を例に話をすすめましょう。

gap.jsを開くと、
Device.soundPlay関数の部分を見ると、

Device.exec()関数というのが実行されているのが分かります。
この関数が、WEBViewへのリクエストを出してくれる関数です。
そしてこの関数への引数は、「gap:sound:鳴らしたい音のファイル名」となっています。
これがWEBviewへ渡すリクエストです。

このリクエストがどのObjective-Cのメソッドで受け取られるかというと、
「GlassAppDelegate.m」の中の、
「- (BOOL)webView:(UIWebView *)theWebView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType」というメソッドです。
このメソッドの中で、渡されたURLを「:」で分割し、配列「parts」へ格納されます。

NSArray * parts = [urlString componentsSeparatedByString:@":"];

▲この部分ですね。

このpartsのインデックス0が「gap」なら通常のHTTPリクエスト以外の処理が行われるわけです。

//LOCATION
if([(NSString *)[parts objectAtIndex:1] isEqualToString:@"getloc"]){

▲この部分以降は、partsのインデックス1の値によって、機能を切り替えるわけです。

soundPlay()関数の場合、「gap:sound:ファイル名」というURLが渡されるので、
partsのインデックス1が「sound」だったときに、指定した音を鳴らす機能を実装してやっているわけです。

else if ([(NSString *)[parts objectAtIndex:1] isEqualToString:@"sound"]) {

// Split the Sound file
NSString *ef = (NSString *)[parts objectAtIndex:2];
NSArray *soundFile = [ef componentsSeparatedByString:@"."];

NSString *file = (NSString *)[soundFile objectAtIndex:0];
NSString *ext = (NSString *)[soundFile objectAtIndex:1];
// Some TODO’s here
// Test to see if the file/ext is IN the bundle
// Cleanup any memory that may not be caught
sound = [[Sound alloc] initWithContentsOfFile:[mainBundle pathForResource:file ofType:ext]];
[sound play];
}

▲それがここですね。
まず、ここで勘のいい人は気付いていると思いますが、
「gap:呼び出したい機能:疑似的な引数1:疑似的な引数2:疑似的な引数3…」
とリクエストするURLの2番目の「:」以降は、
「:」区切りで疑似的な引数を与えることができるのです。
soundPlayの場合は、最初の疑似的な引数へ鳴らしたい音ファイルのファイル名を渡しています。
上記のソースでは、このファイルを「Audio Queue Services」へ登録して鳴らしているわけです。
(Audio Queue Servicesの説明は、cocoaプログラムの作成方法をごらんください)

ざっと説明するとこんな感じです。はいめっちゃ分かりづらい!!笑)
しかし、これくらい読めないといいアプリは作れない!ってことで、
そういう意見はスルーします!

さて、さっきのsoundPlayのAPI、
Objective-Cのソース内では、この機能が呼び出される度に、
「Audio Queue Services」へファイルが登録され、
そしてそのファイルが再生されて終わり。。。という仕様になっています。
これはこれでいいのですが、なんか効率悪いですよね。。。

ってことで次回は、

音ファイルの登録と再生を別のJavascriptAPI関数として実装してみます。
お楽しみに。

PhoneGapでiPhoneアプリ作成をはじめた

ちょっと前に一部の界隈で話題になったHTML+JavascriptでiPhoneアプリ作成を始めてみた。

まずはこの辺(@ITの記事)を参考に・・・。
いくつかのライブラリが出ているようだ。。。

PhoneGap
QuickConnect

というのが良さげだ。

が、しかしQuickConnectはライセンスがLGPL。。。
これはAppStoreで販売・配布しようと思うと制限がありすぎ(>_<;)

一方のPhoneGapはMITライセンス。
これなら大丈夫!
ということでPhoneGap採用!



上記の@ITの記事では、簡易RADとしてのDashCodeを利用してまずHTMLを作成しているが、
この方法だと、iPhoneSDKを十分に使いこなせなさそうだったので、
Xcodeで最初から作るという前提で、
不定期に記事を書いていきます。



まずはXcodeをインストールしてください。ちなみにMacOSX10.5(Leopard)じゃないと後述のiPhoneSDKがインストールできないので、違う人はまずOSを買ってきましょう(^-^;

XcodeはOSのCDの中にあります。



はい、次。iPhoneSDKをインストールします。

だいたいここまでで、1時間くらい要します。XcodeとiPhoneSDKのアップデートはちょくちょくチェックしておいたほうがいいです。
筆者は、iPhoneSDKをアップデートしていなかったがために、PhoneGapのサンプルがビルドできないという「症状」に4時間近く悩まされて今いました(^-^;



じゃ、ここでPhoneGapを登場させます。
ダウンロードして解凍してできたディレクトリの中に「iPhone」というディレクトリがありますので、
その中にXcode用のプロジェクトファイルがあります。
PhoneGap.xcodeproj」を開きます。
もうひとつプロジェクトファイルがありましたが、
筆者の環境ではこちらはなぜか開きませんでした。

公式のwikiに従って、下準備をします。

ここで一回テストでビルドしてiPhoneシミュレータを走らせてみましょう。
Hello!Wordld!が表示されれば、準備完了!



あとは、index.htmlに改良を加えていけばいいわけですが、
いつものHTMLアプリケーションの感覚で、

<a href="javascript:;" onclick="test();">TEST</a><br />
<div id="SET"></div>
<script type="text/javascript">
function test(){
document.getElementById(‘SET’).innerHTML = ‘test!!!’;
}
</script>

って書いたら、大変なことになりました。
こまかい説明はしませんが、
<a>タグを書くとiPhoneシミュレータが落ちますんで使わないほうがいいでしょう。
テキストにonclick属性などをつけたい場合は、
<span>タグを利用します。

画像は、Xcode上で、Resourceディレクトリ内にコピーしてやる事で利用できるようになります。
あくまでコピーです。デフォルトの状態でドロップすると参照になってしまいます。
これでは利用できないので注意してください。
またフォルダの利用は不可です。
かならずindex.htmlファイルと同階層に置く必要があります。
おそらく画像だけでなくJS・CSSファイルもだと思われます。(現時点で未確認)

画像の呼び出しは通常通り、
<img src="ファイル名" />
です。
画像にonclick属性を設定するときは、<a>タグを利用せず、<img>タグの属性とします。

ということで大体全体像がつかめたところで眠くなったので終了。。。zzz

次回はObjective-Cのクラスにアクセスできるのかをやってみますねー。
あと、画像のない記事ですまぬ。