Xojo日本語ブログ

マルチプラットフォーム対応アプリが開発できるXojoのブログです。

Xojoで作るElectron風アプリ

JavaScriptにはElectronという技術があります。これはHTML5/JavaScript/CSSで作られたソフトウェアをネイティブコードでラッピングし、JavaScriptからネイティブアプリでしか扱えない機能を提供するというものです。

同様のことをXojoアプリで行う方法について紹介します。この方法をうまく使うと、Xojoアプリを再ビルドすることなく機能を追加したりバグフィックスできるようになります。

仕組みについて

まず利用するのはHTMLViewerになります。このHTMLViewerからXojoのコードを呼び出す際にはHTMLドキュメントのtitleを変更します。これによってHTMLViewerのtitleChangeイベントが実行されます。

f:id:moongift:20170608101744p:plain

次にXojo側で送られてくるメッセージを解析して処理を行います。最後に HTMLViewer の ExecuteJavaScript を実行して結果を返却します。 ExecuteJavaScript はあらかじめ指定された関数名を実行します。

f:id:moongift:20170608101824p:plain

つまり基本的に処理は非同期で行われる形になります。

メッセージの解析について

Xojo側に送られてくるメッセージが様々ですと解析も大変です。そこでURIを送ってくると言う想定で進めます。この時には以前作成したURLをパースするクラスを使います。

そしてJavaScript側では次のように実行します。

document.title = 'xojo://localhost/hello';

これをURLクラスに渡すことで次のようにデータが得られます。

Dim url as URL = new URL(newTitle)

url.schema // xojo
url.domain // localhost
url.path   // /path

さらにパラメータがある場合も対応しています。

newTitle = "xojo://localhost/files?callback=getFiles&path=/"

Dim url as URL = new URL(newTitle)

url.schema // xojo
url.domain // localhost
url.path   // /files
url.params // callback => getFiles, path => 1

後はこれらの内容に沿ってXojoで実装していくだけです。

Xojoだけで完結する場合

例えばアラートを出すだけであれば次のようになります。

if url.path = "/hello" then
  MsgBox("Hello")
end if

JavaScriptに値を返す場合

ネイティブのデータを取得し、その結果をJavaScriptに返さないといけない場合はExecuteJavaScriptを使います。

Dim callback as string = url.params.Value("callback")
callback = callback + "([" + fileName + "])"
mainHTML.ExecuteJavaScript(callback)

この場合はあらかじめHTML側に用意してある関数に対してデータが返ってきます。

var getFiles = function(files) {
  if (files.length == 0) {
    document.getElementById('files').value = 'ファイルがありません';
  }else{
    document.getElementById('files').value = files;
  }
}

このような関数を多数用意しておくことで、Web技術だけでローカルアプリケーションが作れるようになります。引数で読み込むHTMLファイルを指定して起動できれば、コンパイル不要でアプリケーションが作れるようになります。

デモのコードはmoongift/xelectronにアップロードしてあります。最終的な目標として、引数でHTMLファイルを渡せば、それをアプリケーションとして開けるようにしたいと考えています(現在キャッシュの問題あり)。そうすればxelectronの実行ファイル一つあれば、コンパイルレスでアプリケーションの機能を変えられるようになるでしょう。