Archive for the 'JavaScript' Category

イベントを自動判定する

8月 20 2010 Published by hkitago under JavaScript,コーディング

タッチパネルに対応するアプリケーションを開発する場合、開発は従来のマウスを使うブラウザ環境で行いつつ検証を実機でという手順を繰り返すことになるが、その際にイベントハンドラに記述するマウスイベントとタッチイベントの切り替えを自動的に判定して行う方法を Apple が公開している iAd のサンプルコード内に見つけたので開発しているアプリケーションのコードに適用した。

const BGPSupportsTouches = ("createTouch" in document);
const BGPStartEvent = BGPSupportsTouches ? "touchstart" : "mousedown";
const BGPMoveEvent  = BGPSupportsTouches ? "touchmove"  : "mousemove";
const BGPEndEvent   = BGPSupportsTouches ? "touchend"   : "mouseup";

このように定義しておいて次の様な例で使うと、実機に移植する際に一々コードを置換修正する必要がなくなって便利この上ない。

Anode.addEventListener(BGPStartEvent, this, false);

コメントは受け付けていません。

Scoreboard WebApp

7月 13 2010 Published by hkitago under JavaScript,iOS,iPhone

I apologize for the inconvenience about Scoreboard iPhone App, which is not yet ready for iOS4. And I have straggled to upgrade for development, meanwhile you can go through the following just 2 steps to set up Scoreboard WebApp on your device of iOS4 for free.

  1. Click Scoreboard on Safari of iOS4.
  2. And then, tap + button on the bottom center of the mobile Safari toolbar to add icon on your home screen.

That’s it. Of course, you can use it with fast-app-switcher.

And full screen viewing like a native application.

Stay tuned for update and enjoy.

コメントは受け付けていません。

iOS用お絵描きソフト

7月 02 2010 Published by hkitago under HTML,JavaScript,Safari,iOS,iPhone

iPad の Safari で動作するマルチタッチ対応お絵描きソフトを作ってみた” からコードを拝借し、フルスクリーンで起動するように次のタグを追加してローカル上にある Mac OS のサイトディレクトリに配置した。

"apple-touch-icon"を指定しない場合のホームアイコンはページのスクリーンショットになるので、何か描いた後に “ホーム画面に追加” ボタンを実行すると良い。

デモ (リンクは予告無く削除する事があります)

フルスクリーン表示ではアドレスバーの表示が無いので、白紙に戻す時に使う “再読み込み” は “ホーム>アイコン” とタップ数が多くなってしまう事に注意。

P.S. 子供に遊ばせてみる事にする。

更新: "apple-touch-icon"を指定したウェブアプリは iOS4 のマルチタスクに対応する様だ。

更新2(7/22):子供とお絵描きをして遊んだ。彼は飽きたらホームボタンを押すので同時にスリープボタンを押してキャプチャを撮る事に成功。

コメントは受け付けていません。

SQLiteデータベースにカラムを追加する

3月 16 2010 Published by hkitago under JavaScript,iPhone,コーディング

以前 “SQLiteデータベースのバージョンを変更する“という記事を書いたが、結局実機でもうまく動作しなかった(Safari ブラウザやシミュレータと同じ結果だった)ので、データベースのバージョンによる管理を諦めて単純にカラムを追加することにした。

try {
 if (window.openDatabase) {
  db = openDatabase("BackgammonPositionsDB", "1.0", "Backgammon Positions DB", 200000); /* 現行バージョンのまま */
  if (!db) {
   alert("Failed to open the database on disk.");
   /* 初期化 */
  } else {
   db.transaction(function (tx) { /* 新しいカラムがなければ追加する */
    tx.executeSql("SELECT crawford, star FROM BGPositions;", [],
     function(tx, result) { },
     function(tx, error) {
      tx.executeSql("ALTER TABLE BGPositions ADD COLUMN crawford INTEGER default 0; VACUUM;");
      tx.executeSql("ALTER TABLE BGPositions ADD COLUMN star INTEGER default 0; VACUUM;");
    });
   });
   /* 全行読み込み */
   return;
  }
 } else {
 alert("Couldn't open or support the database. Please try to contact with author.");
  /* 初期化 */
 }
} catch(e) {
 /* former changeVerion.js (前回はここにバージョンを変える関数をいれていた) */
}

Webkit のバグが解消されない限りはこの方法が良いと思う。

さてこのコードを埋めたアップデートファイルが、驚愕のわずか12時間程度で承認され公開(Backgammon Position Cards for iPhone, iPod touch, and iPad on the …)されている。また以前の投稿 “iPhone アプリのアップデートで課金する” で話していた様に価格も元の Tier5 に戻した。

更新(2010年5月11日): 一年間十分食べさせて頂いたのと世界的な不況ということを考慮してTier4に値下げした。:-)

No responses yet

SQLiteデータベースのバージョンを変更する

2月 07 2010 Published by hkitago under JavaScript,Safari,iPhone,コーディング

iPhone アプリで利用している SQLite のスキーマを変更する必要に迫られ開発中に予期せぬ出来事があった。具体的にはテーブルに一列追加する changeVersion という関数を利用する際に必ずバージョンがマッチしないというエラーを出力するというものだ。

success callback である第五引数内でもoj.versionがoldVersionを返すのが気になります、、、。リロードするとようやくnewVersionに変わるんですけれど、これで良いのかなぁ。

引用元: JavaScript++かも日記: 【iPhone】iPhone用 JavaScriptデータベースプログラミング入門 (6).

Safari の JavaScript のデバッガでこの問題を確認し回避策を模索していたところ、Apple の文書に次のような回答を見つけた。

Unfortunately, the only way for your code to see the new version number is by closing the browser window. If you get an error code 2 (see “Error Codes”) and the database version you passed in for the old version matches the version in db.version, you should either assume that the version change already happened or display an alert instructing the user to close and reopen the browser window.

引用元: Safari Dev Center: Safari Client-Side Storage and Offline Applications Programming Guide: Using the JavaScript Database.

結局のところ挙動は問題ないのだけど、ブラウザを閉じるか再読み込みしないと利用者に反映されないということで、次のようなコードにして iPhone の UIWebView 用に移植する前段階として一旦作業を終えることにした。

try {
  if (window.openDatabase) {
  // db = openDatabase("BackgammonPositionsDB", "1.0", "Backgammon Positions DB", 200000); /* 現行バージョンの記述 */
  db = openDatabase("BackgammonPositionsDB", "2.0", "Backgammon Positions DB", 200000);2.0バージョンは開けずエラーをキャッチするので通常の処理は省略)
} catch(e) {
  if (e.code == DOMException.INVALID_STATE_ERR) { // Version number mismatch.
    var prevdb = openDatabase("BackgammonPositionsDB", "1.0", "Backgammon Positions DB", 200000);
    prevdb.changeVersion("1.0","2.0", 
      function(tx){
        tx.executeSql('ALTER TABLE BGPositions ADD COLUMN crawford INTEGER default 0;VACUUM;');}, 
        function(error){ /* SQLエラー処理 */ }, 
        function(){ /* 成功後初期化処理 */ });
    return;
  }
  alert("Unknown error " + e + ".");
}

またこの検証作業に関して SQLite のバージョンを戻す(1.0 に下げる)必要があり、前述した Apple の文書にもある ~/Library/Safari/Databases/ にあるファイルを削除して Safari を再起動するという若干面倒な手続きを取るしか方法がないので、Rails のような管理手法を Automator や AppleScript で作ることが望ましい気がした。

実際の iPhone 上の UIWevView ではどのような挙動になるのか、悩ましいことになるようであれば追って報告しようと思う。

No responses yet

XcodeでJavaScriptを外部ファイルとして扱う

10月 02 2009 Published by hkitago under JavaScript,Xcode,iPhone

UIWebView を使い iPhone のウェブアプリケーションをネイティブアプリケーションとして構築していると、Canvas 描画やタグ出力、Sqlite の扱い等、膨大なコード量になる JavaScript は次の様にしておくとプロジェクトの管理が楽になるのはウェブ開発者であれば誰もが思うところだが、そのままビルドすると Xcode は JavaScript をコンパイルしてしまい外部ファイルとして認識しないという問題がある。

<script src="xxx.js" type="text/javascript"><!--mce:0--></script>

そこで Developer Forums を覗いてみると、次のような回避策が紹介されていたので試してみた。

So you need to do two things – select the .js file in your project, and turn off the checkbox that indicates that it is compiled (the “bullseye” column).  If you don’t do this, you’ll get a warning in your build log about being unable to compile the file (which should be your first warning – always try to figure out and and correct any and all warning that appear in your build).

Then drag it and drop it in the target’s “Copy Bundle Resources”.

引用元: Developer Forums Beta: UIWebView and JavaScript ….

  1. 外部ファイルとして HTML に読み込みたい JS ファイルを選択し、表示メニューから詳細コマンドを選択する。(この詳細表示とエディタの間にあるハンドルをマウスで下方へドラッグしても良い。)
  2. ターゲットのチェックボックスを外す。ターゲットのチェックボックスを外す
  3. グループとファイルのターゲットからアプリケーション名ツリーの中にあるバンドルリソースをコピーに対し対象となる JS ファイルをドロップする。JS ファイルをドロップする

これで Safari ブラウザ等のデバッガと連携する JavaScript プログラムの管理や分業がより容易なものになり、加えて jQuery 等のライブラリも自由に扱える事で開発の効率が上がるのは間違いない(はず)。

更新:Xcode 3.2で検証した結果、チェックボックスのチェックが自動的に復活しているにも関わらず動作しているので手順1と2は不要かもしれない結論に至った。単にバンドルリソースとすれば良いらしい。

No responses yet

移植を視野に入れたウェブアプリ開発

8月 06 2009 Published by hkitago under JavaScript,iPhone,ウェブ,ビジネス

「移植性を無視して最新のハード向けにばりばりのネーティブコードを書きたかったらiPhone向けのアプリをObjective Cで作り、さまざまなデバイスへの移植性が重要ならHTML5+Javascriptでインタラクティブなアプリを作ってiPhone上のSafariでテストしておく」というのが現時点でのスマートフォン向けの開発投資の仕方としては、最も賢い選択肢だと考えている私である。

引用元: Life is beautiful: GoogleのAndroid向けのアプリビジネスはなぜ魅力的ではないか?.

選択肢にした経験から気をつける点が2つ思い当たる。1つ目は iPhone で Canvas が使い物にならないと感じたことだ。具体的には読み込みに時間を必要とし利用者の精神的負荷となる可能性がある。ポジションカードアプリで描いているボードの絵柄は当初 Safari 3 上の Canvas で検証し問題が無いことを確認していたが、実テストに於いて第二世代 iPod touch で且つ OS が v2 だったことを考慮しても、起動に7秒前後を要した。ゲームのようにローディングで対応するということも思いついたが、ユーティリティの部類では難しいと判断した。

2つ目はスコアボードアプリの開発に於いて実践し学んだことで、こちらは manifest ファイルを記述したウェブアプリ版を先行して公開していたのだが、それら2つの機能差に明確な優位性が無かったことから販売台数は伸び悩んでいる。結果として無計画になってしまった理由は Apple の開発者向け戦略が勇み足だったというか、iPhone SDK 公開の流れでお分かり頂けると思う。

さらに、この方法を後発のポジションカードアプリ開発に適用しなかったのはこのような外的要因に加え、上述したような場合に、水平モードに固定できず Safari のツールバーが邪魔をして描画領域を確定できなかったことが挙げられる。これらの問題がクリアできれば車輪を再開発することなく移植はもちろん、ウェブアプリとして無料版に仕立てることも可能だと思う。

実際に手を動かす視点では ActionScript を使えれば OpenGL も楽しいだろうと思う反面、ビジネス的にはクラウドネットワークについて考えてしまうので SQLite を直接扱える JavaScript を選択し iPhone 市場に参入した次第だが、そんな技術話よりも米国の顧客からはブラックベリーや Facebook といった別プラットフォームへの移植の需要があるのは確かだ。しかし開発環境が無いからと断っているのは、競合が皆無でロングテール(素麺代稼ぎ)を楽しんでいるという反省すべき点がある。;-)

最後にウェブ開発者という視点で見ると、重い Parallels を使った貧そな UI を持つ IE の動作確認から逃れ、ミドルウェアを使わずにデータを入出力できる新しい技術を試す興奮や楽しさを得られたと思う。日本の自称ウェブ業界スーツ民達に技術の理解が浸透し、仕事として回り出すのはいつのことになるのだろうと思ったが、広報の方法が変化するように、案件が降りてくるのを待つよりも昨年の不況が転換期のような気もするので、日々精進あるのみと再度自省する。

P.S. Interview with Neil Mix of Pandora – iPhone Audio Streaming, Memory Management, and More も JavaScript を iPhone に利用する面白い例だと思うので参考迄。

No responses yet

文字連結の処理速度

7月 13 2009 Published by hkitago under JavaScript,PHP,コーディング

具体的に文字列連結はHTMLタグを出力するために使用することが多く処理の速度は気になるところだ。

文字列を加算していくのは、計算の途中で、abcde、abcdeabcde、abcdeabcdeabcdeという文字列オブジェクトがその都度生成されていくのでメモリにやさしくない。巨大な文字列の連結にはjoinを使ったほうが良い。数が大きくなると速度に差が出てくる。

引用元: 最速インターフェース研究会 :: 実践JavaScriptリファクタリング.

PHPの結果が気になったのでこちらの記事を参考に(若干コードを変更)して実験してみたところ、連結の方法が最も速いと言う結果になった。元記事のサンプルコードでも統計的に同じ結果(DoS攻撃してスミマセン)なので、PHPのバージョンや環境の明記が必要だと思った。尚今回の環境はMac OS X 10.5.7のPHP 5.2.8 (cli) (built: Feb 5 2009 21:21:13) をApache/2.2.11 (Unix) (Server built: Feb 3 2009 01:54:45)のモジュールとして利用している。

特にIEで顕著なのだが、JavaScriptはappendChild関数を使うより文字連結したタグをinnerHTML関数で差し込む方が速いということも同種の問題が起因しているのだろうか。これらの問題は、コンピュータ上のWebkitやChromeであれば意識する必要もあまりないのかもしれないが、iPhoneなど非力ハード上ではまだまだ注意すべき問題だろう。

screen-capture-11

// 追記編
$time1 = getmicrotime();
$str = null;
for($n = 0; $n &lt; $count; $n++){
    $str.= $str1;
    $str.= $str2;
    $str.= $str3;
}
$time1 = getmicrotime() - $time1;
 
// 連結編
$time2 = getmicrotime();
$str = null;
for($n = 0; $n &lt; $count; $n++){
    $str.= $str1.$str2.$str3;
}
$time2 = getmicrotime() - $time2;
 
// 非連結編
$time3 = getmicrotime();
$str = null;
for($n = 0; $n &lt; $count; $n++){
    $str.= "$str1$str2$str3";
}
$time3 = getmicrotime() - $time3;
 
// 配列編1
$time4 = getmicrotime();
$arr = array();
for($n = 0; $n &lt; $count; $n++){
  array_push($arr, $str1, $str2, $str3);
}
$str = implode('', $arr);
$time4 = getmicrotime() - $time4;
 
// 配列編2
$time5 = getmicrotime();
$arr = array();
for($n = 0; $n &lt; $count; $n++){
  $arr[] = $str1;
  $arr[] = $str2;
  $arr[] = $str3;
}
$str = implode('', $arr);
$time5 = getmicrotime() - $time5;

No responses yet

bodyタグの前にJavaScriptを書く

7月 11 2009 Published by hkitago under JavaScript

bodyタグの前にJavaScriptを書いてしまったがために存在しない要素にアクセスしようとしてバグってしまうこと

引用元: 第133回 JavaScriptだけ学んでいても動的なページを作れるようになれない DOMが必要だ – bingo_nakanishiの他言語出身者のためのPerl入門.

bodyタグの前にJavaScriptを書くことが問題ではなく、要素が読み込まれる順序と呼び出し方が適していないことが問題だと思う。具体的には次のようにイベントリスナーを使うと良いのではないだろうか。

window.addEventListener("load", function() {
// Do something.
}, false);

アプリケーションの規模が大きくなることが予想されるのならば可能な限りbodyタグの中にスクリプトを埋め込まないようにした方が良いと思うのは、維持管理を考慮してのことになる。もちろん不要になるまでの周期が早い使い捨てプログラムであれば、コードカウボーイの如く後先考えずにコードを埋め込んだ方が幸せだと思う。

No responses yet

[The HTML that caused this error was generated by a script.] Unmatched </embed> encountered. Ignoring tag.

6月 24 2009 Published by hkitago under Flash,HTML,JavaScript

VeriSign が使っている検証バッジはブログパーツのような方法で出力しているのだが、EMBED タグについて <embed></embed> のように書いてしまうと “[The HTML that caused this error was generated by a script.] Unmatched </embed> encountered. Ignoring tag.” という JavaScript エラーをコンソールが出力していることが分かった。

<embed />とすると解決する。

No responses yet

Next »