Webサイトがレスポンシブデザインになったり、JavaScriptを駆使した高度なWebアプリケーションのようになっていくと、そのままアプリとしてみても遜色なくなってきます。そして、Webサイトをアプリ化したいというニーズが出てきます。

本格的にアプリとして作るならばWeb APIを作って通信するのが良いですが、今回はMonacaのInAppBrowserを使って簡易的にアプリ化する方法を紹介します。

InAppBrowserの使い方

InAppBrowserはアプリ内に別ブラウザを表示するプラグインです。元々Monacaアプリに組み込まれたプラグインなので、誰でも利用できます。

使い方としては次のようになります。

var ref = window.open('URL', '_blank', 'OPTIONS');

URLは表示するURLを指定します。OPTIONSは様々にあるのですが、全画面表示でURLの表示やボタンなどもなくす場合は location=no,presentationstyle=fullscreen,toolbar=no と指定するのが良いでしょう。例えば次のようになります。

var ref = window.open('https://onsen.io/blog/', '_blank', 'location=no,presentationstyle=fullscreen,toolbar=no');

これだけで次のような表示になります。

開発中の工夫

これで完了なのですが、アプリの開発中には再読み込みしたいということがあると思います。しかし、InAppBrowserで全画面表示にしているとMonacaデバッガーのボタンも見えなくなってしまいます。元々のMonacaアプリのWebViewからInAppBrowserは閉じられるのですが、その逆はできません。

同じような問題にハマっている方は多いらしく、Cross Window Communication With Cordova's InAppBrowserに方法がありました。

まず、InAppBrowserには独自のJavaScriptを流し込めます。ファイルを指定することができるはずなのですが、うまくいかないので、代わりにコードを直接指定することにします。

via ios - InAppBrowser inject script (using executeScript) - Stack Overflow

InAppBrowserのloadstopイベントを使って読み込み完了を検知します。その上で、Ajaxを使ってアプリ内のJavaScriptファイルを取得します。そして、その内容をInAppBrowserのexecuteScriptを使って実行します。

var ref = window.open('https://onsen.io/blog/', '_blank', 'location=no,presentationstyle=fullscreen,toolbar=no');
ref.addEventListener('loadstop', function() {
  $.get("myscript.js", function(data) {
    ref.executeScript({code: data});
    :
  });
});

myscript.jsですが、次のようになります。

まず最初にlocalStorageを初期化しています。このlocalStorageを使って、WebViewとInAppBrowserで情報のやり取りをします。

localStorage.setItem('window_close', null);
$("body").append('<div class="page-back" style="position: fixed;bottom: 10px;right: 10px;"><a class="back" href="#header">Close</a></div>');
$(".back").on('click', function(e) {
    e.preventDefault();
    localStorage.setItem('window_close', true);
});

そして、bodyタグに対してCloseというラベルを追加しています。このラベルを押した時のイベントとして、localStorageのwindow_closeというキーをtrueにします。

親のWebViewでは、setIntervalを使ってInAppBrowserのlocalStorageを定期的に監視します。そして値がtrueになったら、InAppBrowserを閉じます。

var loop = setInterval(function() {
    ref.executeScript({
        code: "localStorage.getItem('window_close')"
    }, function( values) {
        if (values[0] === 'true') {
            clearInterval( loop );
            ref.close();
        }
    });
}, 2000);

今回はjQueryを使っているので$オブジェクトを使っていますが、他のライブラリの場合はそれぞれ読み替えてください。親ウィンドウのスクリプトは次のようになります。

<script>
    function onDeviceReady() {
      var ref = window.open('https://onsen.io/blog/', '_blank', 'location=no,presentationstyle=fullscreen,toolbar=no,transitionstyle=coververtical');
      ref.addEventListener('loadstop', function() {
            $.get("myscript.js", function(data) {
                ref.executeScript({code: data});
                var loop = setInterval(function() {
                    ref.executeScript({
                        code: "localStorage.getItem('window_close')"
                    }, function( values) {
                        if (values[0] === 'true') {
                            clearInterval( loop );
                            ref.close();
                        }
                    });
                }, 2000);
            });
        });
    }
    document.addEventListener("deviceready", onDeviceReady, false);
</script>

これを実際に動かすと次のようになります。

アプリが立ち上がったタイミングで外部のURLが表示されます。そして、右下にあるCloseというラベルをタップすると、ウィンドウが閉じるという流れです。

実際のアプリとして出す際には閉じるアクションは不要だと思うので、デバッグ用のフラグを設けて表示を制御すると良いのではないでしょうか。

InAppBrowserプラグインの詳しい使い方はInappbrowser プラグイン - Monaca Docsをご覧ください。