Asial Blog

Recruit! Asialで一緒に働きませんか?

PhoneGapアプリ開発のちょっとしたコツ

カテゴリ :
フロントエンド(HTML5)
タグ :
PhoneGap
HTML5
iPhone
Android
PhoneGapはスマートフォンにてハイブリッドアプリケーションを作成するためのフレームワークです。この記事では、PhoneGapによりワンソース・マルチユース(クロスプラットフォーム)なアプリを開発するためのコツをご紹介します。

従来まで、スマートフォンアプリの開発形態は、

・ネイティブアプリ
・Webアプリ

に大別されていました。ネイティブアプリでは端末の機能を全て活用できる一方で、クロスプラットフォーム性がありません(iOSとAndroidで別々に実装)。他方、WebアプリではWebViewを使ったり、ブラウザを使用することで、HTML5などの機能を使用します。これにより、クロスプラットフォーム性が担保されています。一方で、ネイティブ機能を利用できない、などの制約も発生していました。

PhoneGapを使用したハイブリッドアプリは、上記の2つの手法の間に存在し、次の特徴を持っています。

・HTML5によるビューの実装
・クロスプラットフォーム性
・端末機能の使用

一見、良いことだらけのように見えます。しかし、実際にプロジェクトで使用し、iOSとAndroidの両方に適用しようとなると、様々な問題につきあたります(当然のことながら)。多くの問題とその解決方法の中から次の4つについてご紹介します。

① Android, iOS4, iOS5の区別
② javascriptの読み込み
③ DOMContentLoaded
④ ライブラリ(jQuery OR Zepto)



① Android, iOS4, iOS5の区別


javascriptによりnavigatorのuserAgent, appVersionなどを使用して切り分けます。特に、iOS4とiOS5とではCSSなどで挙動が異なる部分が多く、区別は必須です。以下に一例を示します。

  1. var IS_ANDROID = (/android/gi).test(navigator.appVersion);
  2. var IS_IOS4    = navigator.userAgent.match(/OS 4_[0-9_]+ like Mac OS X/i) !== null;
  3. var IS_IOS5    = navigator.userAgent.match(/OS 5_[0-9_]+ like Mac OS X/i) !== null;

こういった値を何らかのオブジェクトにまとめておくと、とても便利です。


② javascriptの読み込み


画面数が増えるに従い、javascriptファイルが増えるに従い、javascriptファイルを読み込み・使用することが多くなります。その一方で、javascript言語の仕様上、依存関係を各ファイルに記述できません。そんな時には、scriptタグを書きだすスクリプトファイルを1つ用意します。そして、そのファイルを各画面にて読み込みます。例えば、次のようになります。

main.js

  1. var IS_ANDROID = (/android/gi).test(navigator.appVersion);
  2.  
  3. (function() {
  4.   var phonegapJs = '';
  5.  
  6.   // PhoneGapライブラリの設定
  7.   if(IS_ANDROID) {
  8.     phonegapJs = 'phonegap-android.js';
  9.   } else {
  10.     phonegapJs = 'phonegap-ios.js';
  11.   }
  12.  
  13.   // 読み込むファイルのリスト生成
  14.   var scripts = [
  15.     // 各種ライブラリ
  16.     'js/vendor/phonegap/' + phonegapJs,
  17.     'js/vendor/zepto/zepto.js',
  18.  
  19.     // アプリ固有のスクリプト
  20.     'js/app/...',
  21.     '...'
  22.   ];
  23.  
  24.   for (var i = 0, len = scripts.length; i < len; i++) {
  25.     loadScript(scripts[i]);
  26.   }
  27. })();
  28.  
  29. function loadScript(filename) {
  30.   // 以下のように書かないと、xcodeでのハイライトがおかしくなる
  31.   // 実際には、普通にdocument.writeでタグを書きだしても良い
  32.   var script = '%3Cscript type="text/javascript" src="' + filename + '"%3E%3C/script%3E';
  33.   document.write(unescape(script));
  34. }


そして、各HTMLファイル内にて、まず上記のスクリプトを読み込みます。

index.html

  1. <html>
  2. <head>
  3.   <script type="text/javascript" src="js/main.js"></script>
  4.   ...
  5. </head>
  6. <body>
  7.   ...
  8. </body>
  9. </html>

極々当たり前のことですが、これだけでかなり楽になります。同時に、javascriptファイルを分割できるため、コード自体も読みやすくなります(分割には賛否両論ありそうですが・・・)。また、require.jsなど、似たような機能を持ったライブラリもあります。興味のある方は、お試しください。

③ DOMContentLoaded


DOMContentLoadedイベント内にて、devicereadyイベントをバインドしましょう。DOMContentLoadedイベントは、DOMの読み込みが終わった際に発生します(これ以降、DOMを使えます)。

PhoneGapでは、プラグイン機構を通じてネイティブ機能へアクセス可能です。ただし、アクセスできる条件として、PhoneGapにより、javascriptのdevicereadyイベントが発生している必要があります。

  1. document.addEventListener('deviceready', function(){
  2.   // この中でアプリの内容・ロジックを実行する
  3. });

実際にアプリの内容を実行する際には、DOMを活用したり、CSSを使ったりと、HTMLの構造を必ず利用します。そのため、HTML構造などが読み込まれてからdevicereadyをバインドする必要があります。次のように、BODYタグのonLoadやloadイベントでバインドすることも可能です。

  1. <html>
  2. <head>
  3.   <script type="text/javascript" src="phonegap.js"></script>
  4.   <script type="text/javascript">
  5.     function onBodyLoad() {
  6.       document.addEventListener('deviceready', onDeviceReady);
  7.     }
  8.  
  9.     function onDeviceReady() {
  10.       // PhoneGap開始後の処理を記述する
  11.     }
  12. </script>
  13. </head>
  14. <body onLoad="onBodyLoad();">
  15.   <div>...</div>
  16.   <div>...</div>
  17.   <div>...</div>
  18. </body>
  19. </html>

ただ、onLoadやloadイベントはDOMContentLoadedイベントに比べて遅くなる場合があります。というのも、画像ファイル等の読み込みも待ってしまうからです。そのため、アプリの開始が遅れる恐れがあります。DOMContentLoaded発生時にdevicereadyをバインドする方法は、次の通りです。

  1. <html>
  2. <head>
  3.   <script type="text/javascript" src="phonegap.js"></script>
  4.   <script type="text/javascript">
  5.     document.addEventListener('DOMContentLoaded', function(){
  6.         document.addEventListener('deviceready', onDeviceReady);
  7.     });
  8.  
  9.     function onDeviceReady() {
  10.       // PhoneGap開始後の処理を記述する
  11.     }
  12.   </script>
  13. </head>
  14. <body>
  15.   <div>...</div>
  16.   <div>...</div>
  17.   <div>...</div>
  18. </body>
  19. </html>

④ ライブラリ(jQuery OR Zepto)


javascriptの操作性や利便性を向上させるライブラリとしては、Zeptoを使いましょう。ZeptoはjQeuryからIE対応を取り除いた、軽いライブラリです(jQueryに比べて)。スマートフォン用のjQueryと思って下さい。jQueryも便利ですが、スマートフォンで使うとかなり重くなります。



まずは、極々基本的なお話をしました。実際、使ってみると、PhoneGapやHTML5でのスマートフォンアプリ開発がかなりスムーズになります。機会があれば、ぜひ試してみて下さい。