この翻訳は不完全です。英語から この記事を翻訳 してください。
この記事はFirefoxOSや他のプラットフォームで動作するインストール可能なオープンWebアプリの作り方や標準的なWebアプリ/サイトとの違いを記載しているクイック記事です。
このWebアプリ開発者とネイティブモバイルアプリ開発者向けにとって意味のあるように書かれています。
オープンWebアプリは本質的に一般的なWebサイトやWebアプリと変わりはありません。
一般的なオープンWebテクノロジー(HTML/CSS/JavaScript..etc)を使い、ブラウザを介してアクセスできます。
主な違いは、機器にインストールできることやオフラインで動作すること、カメラ、ジャイロセンサー・アドレス帳などの機器固有の機能を利用できるアドバンスAPIへアクセスできること、そして無償/有償アプリを公開するためのMarketplaceを含むエコシステム固有の開発者がいることです。
一般的に、彼らはオープンでクロスプラットフォームテクノロジーに基づく”アプリ体験”を提供します。
オープンWebアプリは特にWeb開発者やモバイル開発者にとって敷居が低いものです。それらの開発者はネイティブに比べより多くのプラットフォームに移植し、特定の垣根にとらわれていないためです。
Note: MozillaのオープンWebアプリはFirefox OSでインストール可能です、そして、Firefoxをサポートしている他のプラットフォームでもMozillaのWebランタイムテクノロジーを利用してインストール可能です。詳細は Open web apps for Android と Open web apps for Desktop をご覧ください。将来的には技術が標準化されるべきであり、多くのプラットフォームで採用されています。
Firefox OS
Firefox OS(Boot to Gecko またはB2Gのコードネーム)はMozillaのオープンソースモバイルOSです。それは、Geckoベースのランタイム環境が起動し、オープンWebアプリがインストール・起動できるLinuxベースのOSです。GeckoはFirefoxがWebコンテンツを表示・レンダリングに利用しているレンダリングエンジンです。
Firefox OSはプレインストールされたGaiaと呼ばれるアプリケーションのスイートが存在します。それは電話での設定やコール、SMS、写真撮影・保存などの電話の基本機能をハンドリングします。
Firefox OSのバージョン毎のサポート
Firefox OSのアプリを開発する際には、顧客が利用しているプラットフォームバージョンを念頭に置いておくよう注意しないといけません。(Firefox OS 端末とその仕様のリストをご覧ください)
デスクトップソフトウェアよりも端末プラットフォームのアップデートは容易にされない事を覚えておいてください。利用ユーザーはネットワークプロバイダに縛られる傾向にあります。そのために、これらのバージョンをサポートしたアプリを開発する必要があります。
箱から取り出された新しいFirefox OSをサポートしたコンシューマー向けFirefox OSデバイスが現れるように、この問題はすぐに消え去ってしまいます。
現在の開発推奨しているベースラインプラットフォームはFirefox OS 1.1です。
MDNのWeb platform reference pagesにはブラウザ/プラットフォームのサポート状況が含まれます。それに加え、アプリ開発のためのAPIリファレンスでより多くのAppテクノロジー仕様のサポート状況を見つける事ができます。
例えば複数行のFlexboxはFirefox OS 1.3以下では動作しません。だから、シンプルなレイアウトを利用するか、古いバージョンのfallbackを提供する必要があります。
必要スキル
既に説明してある通り、オープンWebアプリはHTML,CSS,JavascriptなどのWebテクノロジーに基づいています。だからあなたがWebページを書けるのであれば基礎知識は既にあります。
もし基礎知識を持っていなかったとしても、このガイドに簡単に従えます。しかし、オープンWebテクノロジーを使った開発を学ぶために、Beginner's tutorials のリストをチェックしておいた方が賢明です。
必要ツール
オープンWebアプリ開発をするためにはシンプルなフリーツールまたは既にあるWebエディターツールがあればできます。我々は以下のツールを推薦します。
- シンプルなテキストエディタ:Sublime Text (trial for free), Gedit (free), Notepad++ (free), or Brackets (free, and built with HTML, CSS, and JavaScript)
またはより複雑なIDE:Eclipse (free) or Dreamweaver - アプリをテストするためのFirefoxそして他のモダンブラザ。Firefoxは利用しやすい標準的なデバッギングツールが付属され、さらにテストを支援するためのFirefox OS App Managerも提供されています。
一度開発をしたら、アプリをFirefox OSの実機で動かしたいと思うはずです。開発者向け端末や、あなたが既に存在するデバイス用にビルドしてインストールする事もできます。GoogleNexusモデルのいくつかはサポートされています。
初めてのアプリ
このセクションでは、すばやくインストール可能なWebアプリを構築し実行するために、早く簡単に基礎知識を習得する事を目的としています。もしこのガイドを長く見る必要がない場合は、Githubのquickstart starter templateレポジトリを見てください。(直接zipをダウンロード)
クイックスタートアプリテンプレート
我々のアプリはとてもシンプルです。それはBattery Status APIを使って機器のバッテリー状態を監視し、バッテリーが充電中かどうかを監視して、状態をユーザーに対してバイブレーション(Vibration API経由)やシステム通知(Notification API経由)を使って警告するものです。
まず始めに、スタートテンプレートのディレクトリ構成は以下の構造となっています。
- battery-quickstart-starter-template/
- index.html
- images/
- battery.svg
- icon-128.png
- icon-512.png
- scripts/
- battery.js
- install.js
- style/
- style.css
- .htaccess
- README.md
index.html
: アプリケーションのコンテンツとそこで展開されるもの以外すべてが含まれるメインのドキュメントです。images
: アプリのUIで利用されるアイコンが含まれる。それに加え、Firefox Marketplace(もし公開するのであれば)やインストールされたデバイスのホームスクリーン(そして潜在的な他の場所も同様)のアイコンとなります。アプリのアイコンに関しての詳しい情報はIcon implementation for appsガイドを読んでください。scripts
: アプリの機能を定義したJavaScriptコードが含まれます。現在は2つのブランクファイル(battery.jsとinstall.js)が存在します。style
: 基本スタイルを提供するためのスタイルシートが含まれます(style.css)。.htaccess
: 次章で追加するmanifestのMIMEタイプをサーバーに通知するためのサーバー設定ファイルです。これはサーバーがmanifestファイルを知らなかった場合にエラーを投げないようにするためのものです。README.md
: このレポジトリを説明するためのGithubで利用するマークダウンReadmeファイルです。
manifestを追加する
すべてのオープンWebアプリはアプリのルートフォルダにmanifest.webappを配置する必要があります。これはアプリの重要な情報(バージョン・名前・説明・アイコンロケーション・ロケール設定・インストール可能なドメイン・その他)を提供します。
以下のプレーンテキストファイルをアプリルートに追加して、名前をmanifest.webapp
としてください。
{ "name": "Battery", "description": "Battery provides a good template for an in-app battery/charge indicator with different visualization choices, plus ideas of what could be changed once battery level gets low.", "launch_path": "/index.html", "icons": { "128": "/images/icon-128.png", "512": "/images/icon-512.png" }, "developer": { "name": "Chris Mills", "url": "https://www.conquestofsteel.co.uk" }, "permissions": { "desktop-notification": { "description": "Needed for creating system notifications." } } }
Note: ここで何をしているか正確に知りたい場合は、アプリマニフェストを参照してください。
Note: manifestファイルに記載するパスは必ずサーバーローケーションのoriginからの相対パスを記載してください。例えばアプリルートがhttps://www.mysite.com/myapp/
の場合で、アイコンがhttps://www.mysite.com/myapp/myicon/icon.png
だった場合、manifestのアイコンパスは/myicon/icon.png
ではなく、/myapp/myicon/icon.png
と書くべきです。
APIパーミッション
特定の機能を有効にできるパーミッションを番号で指定します。インストール済みのアプリは上記manifestでNotification APIでシステム通知を制御するためにパーミッションを要求しているように、manifest.webapp
ファイル内に"permissions"フィールドを記載してパーミッション要求を登録する必要があります。
それぞれのAPI毎に要求するパーミッションは異なります。以下のように三つのパーミッションレベルが存在します。
- Normal — 特殊なアクセスパーミッションを必要としないAPI
- Privileged — アプリ内で利用可能なAPI。manifestファイルにアクセス許可を設定し、信頼されたソースコートどして公開することができる。
- Certified — 電話やメッセージサービスのようにデバイスにとってクリティカルな機能を制御するAPI。一般的にサードパーティの開発者は利用することはできません。
Note: API毎の必要なパーミッション情報については、アプリの許可設定を参照してください。
Web API 機能
JavaScript APIはデバイス上にすでに存在し、強化されています。MozillaもJavaScript APIとして標準モバイル機能をいくつももたらしています。
サポートしている機能を検出する
Web開発で一般的に用いられる一つの技術としてJavaScriptの機能検出があります。あなたが実際にその機能を使用する前に、その機能がブラウザでサポートしていることを確認するために実行するコードのことです。もし、サポートされていないのであればフィードバックを返してあげることができます。以下のスニペットは簡単なサンプルを示しています(このサンプルは使わないようにしてください)
// Let's check if the browser supports notifications if (!("Notification" in window)) { console.log("This browser does not support notifications."); }
クイックスタートサンプル機能のコード
scripts/battery.js
ファイルに以下のコードを追加し、コメントを注意深く読んでくさい。まず最初に必要となる変数を設定します。
// fork the navigator.battery object depending on what prefix the viewing browser uses var battery = navigator.battery || navigator.mozBattery || navigator.webkitBattery; // grab the elements we need, and put them in variables var indicator1 = document.getElementById('indicator1'); var indicator2 = document.getElementById('indicator2'); var batteryCharge = document.getElementById('battery-charge'); var batteryTop = document.getElementById('battery-top'); var chargeIcon = document.getElementById('battery-charging'); // Flag to check if battery charged/not charged has already been notified once // 0 for first time of notification, // 1 means "charged" has already been notified, // 2 means "not charged" has already been notified // This is set to the opposite after each notification, so that you don't keep // getting repeat notifications about the same charge state. var chargingState = 0;
次に、バッテリー関連のイベントに発火して、表示されているバッテリー状態の情報を更新するための updateBatteryStatus()
関数を追加します。
function updateBatteryStatus() { // battery.level can be used to give us a percentage of bettery charge to report to // the app's user var percentage = Math.round(battery.level * 100); indicator1.innerHTML = "Battery charge at " + percentage + "%"; batteryCharge.style.width = percentage + '%'; if(percentage >= 99) { // report that the battery is fully charged, more or less ;-) batteryTop.style.backgroundColor = 'limegreen'; batteryCharge.style.backgroundColor = 'limegreen'; createNotification("Device battery fully charged."); } if(battery.charging) { // If the battery is charging if(chargingState == 1 || chargingState == 0) { // and if our chargingState flag is equal to 0 or 1 // alter the styling to show the battery charging batteryTop.style.backgroundColor = 'gold'; batteryCharge.style.backgroundColor = 'gold'; indicator2.innerHTML = "Battery is charging"; chargeIcon.style.visibility = 'visible'; // notify the user with a custom notification createNotification("Device battery now charging."); // flip the chargingState flag to 2 chargingState = 2; } } else if(!battery.charging) { // If the battery is NOT charging if(chargingState == 2 || chargingState == 0) { // and if our chargingState flag is equal to 0 or 2 // alter the styling to show the battery NOT charging batteryTop.style.backgroundColor = 'yellow'; batteryCharge.style.backgroundColor = 'yellow'; indicator2.innerHTML = "Battery not charging"; chargeIcon.style.visibility = 'hidden'; // notify the user with a custom notification createNotification("Device battery is not charging."); // flip the chargingState flag to 1 chargingState = 1; } } }
そして、上記関数で参照されているcreateNotification()
関数を追加します。この関数が呼ばれると、システム通知は引数として渡されたメッセージを含んで発火します。このコードはちょっと長く見えますが、FirefoxとChrome(Blinkベース)ブラウザの両方のNotificationをサポートすることを検出し、両方のブラウザで安心してハンドリングできるようにしています。
function createNotification(message) { // Let's check if the browser supports notifications if (!("Notification" in window)) { console.log("This browser does not support notifications."); } // Let's check if the user is okay to get some notification else if (Notification.permission === "granted") { // If it's okay let's create a notification // show the notification var notification = new Notification('Battery status', { body: message }); // And vibrate the device if it supports vibration API window.navigator.vibrate(500); } // Otherwise, we need to ask the user for permission // Note, Chrome does not implement the permission static property // So we have to check for NOT 'denied' instead of 'default' else if (Notification.permission !== 'denied') { Notification.requestPermission(function (permission) { // Whatever the user answers, we make sure Chrome stores the information if(!('permission' in Notification)) { Notification.permission = permission; } // If the user is okay, let's create a notification if (permission === "granted") { // show the notification var notification = new Notification('Battery status', { body: message }); // And vibrate the device if it supports vibration API window.navigator.vibrate(500); } }); } }
最後に、バッテリーの充電状況・充電レベルの通知を受けるためにbatteryオブジェクトに対してイベントハンドラーを追加します(updateBatteryStatus()
が動作するようにする)。そして、初回表示のためにupdateBatteryStatus()
を実行します。
// Event handler to check whether the battery has started charging or stopped charging battery.addEventListener("chargingchange", updateBatteryStatus, false); // Event handler to check whether the battery charge level has changed battery.addEventListener("levelchange", updateBatteryStatus, false); // run the central function once when the app is first loaded updateBatteryStatus();
コメントはコードがどのように動作しているかを説明していますが、ここで覚えてほしいことは、シンプルなイベントとchargingchange
やbattery
/Notification()
などの簡単なオブジェクトのAPIを使ってハードウェアのデータと機能を使うことは簡単だということです。
JavaScriptはバッテリーの充電レベル変化やバッテリー充電の開始/終了を監視し続けます(chargingchangeやlevelchangeイベントリスナーを使って)。それらのイベントが発生した際に、updateBatteryStatus()
関数が動作し、ユーザー通知するか判断し、視覚的な表示を合わせて更新し、createNotification()
を実行します。
最後の関数が発火した際に、システム通知を行うのと同時にバッテリー状態がどうなったかユーザーにフィードバックするためにデバイスのバイブレートで通知しています。
Note: デバイスAPI状態がアップデートされているか WebAPI pageをチェックしてください。
インストールAPI機能
サンプルのアプリテンプレートには、Firefox上のアプリとしてインストールするために標準Webページとして表示された際にクリックできるインストールボタンを実装しています。ボタンマークアップでは特別な事はしていません。
<button id="install">Install app on device</button>
インストールAPIを使ってボタンの機能実装をします。scripts/install.js
ファイルに以下のコードを追加してください。
// get a reference to the install button var button = document.getElementById('install'); // if browser has support for installable apps, run the install code; it not, hide the install button if('mozApps' in navigator) { // define the manifest URL var manifest_url = location.href + 'manifest.webapp'; function install(ev) { ev.preventDefault(); // install the app var installLocFind = navigator.mozApps.install(manifest_url); installLocFind.onsuccess = function(data) { // App is installed, do something if you like }; installLocFind.onerror = function() { // App wasn't installed, info is in // installapp.error.name alert(installLocFind.error.name); }; }; // if app is already installed, hide button. If not, add event listener to call install() on click var installCheck = navigator.mozApps.checkInstalled(manifest_url); installCheck.onsuccess = function() { if(installCheck.result) { button.style.display = "none"; } else { button.addEventListener('click', install, false); }; }; } else { button.style.display = "none"; }
何度も言いますが、コメントは何をしているか書かれていますが、要するに最初にmozAppsオブジェクトがブラウザ上に存在するかチェックしています(if('mozApps' in navigator)
)。すなわち、インストール可能アプリをブラウザがサポートしているかどうかのチェックです。もしサポートしていない場合、インストールボタンを非表示にします。
次に、navigator.mozApps.checkInstalled を使い、manifest_url
のmanifestに定義されているアプリが既にデバイスにインストールされているかチェックします。もしこのテストが成功した場合、成功イベントが発火し、installCheck.onsuccess = function() { ... }
が実行されます。
installCheck.result
で存在をテストした後、もし存在していればアプリはインストール済みと判断し、インストールボタンを非表示にします。もしアプリがインストールされていなければ、ボタンがクリックされたときにinstall()
関数が実行されるように、click
イベントリスナーをボタンに追加します。
ボタンがクリックされ、install() 関数が実行されたとき、navigator.mozApps.install(manifest_url)を使ってアプリをインストールします。そして、インストールへの参照をinstallLocFind
変数へ格納します。インストールが成功・失敗時にアクションを実行できるようにインストールもまたsuccess
とerror
イベントを発火している事に気づいた事でしょう。
Note: インストール可能なオープンWebアプリは"single app per origin"セキュリテリポリシーを持っています。それは基本的にインストール可能アプリは1つ以上のorigin以外のホストにアクセスする事はできません。少しトリッキーなテストになりますが、この問題を解決するために 異なるサブドメインを作るなど回避策はあります。
オフラインで動作するようにする
デフォルトではWebアプリ(サーバー上から提供されているFirefox OSアプリも含む)はオフラインでは動作しません。リソースは一般的なWebと同じようにキャッシングされていますが、オフラインでアプリがリソースを入手できる事は保証されていません。アプリがオフラインで動作するようにするためのテクノロジーやテクニックは数種類あり、オフラインサポートページにも詳しい情報が説明されています。
アプリをテストする
ここまでくると、アプリ作成は終わったのでブラウザを使ってテストする事ができます。もしうまく動作しない場合は、作成済みのソースコードと照らし合わせてみるかオンラインで動作しているサンプルを見てみると良いでしょう。デスクトップコンピュータでは以下のように動作します。
デスクトップ版Firefox上でテストする
アプリの基本機能のテストをしたいのであれば、シンプルにデスクトップ版Firefox上でロードすればよいです(index.html
ファイルをブラウザで開く)。ここで説明されているほとんどの機能は既にサポートされています。 Mac OS Xでは以下のように動作します。
デスクトップ版Firefoxでインストール可能アプリをインストールできたのと同じく、Firefoxランタイムが含まれるFirefox Aurora/Nightlyそして Firefox for Androidでもインストール機能をテストする事は可能です。
Note: 同じオリジンで他にインストール可能アプリが存在しないサーバー上にファイルをおかないといけない事を心に留めておいてください(異なるサブドメインでは問題ありません)。もし試しに既にGithubで動作しているバージョンのアプリをインストールしようとすると、MULTIPLE_APP_PER_ORIGIN_FORBIDDEN
エラーが出るでしょう。
Firefox OS シミュレーターでテストする
App Manager (または、間もなく新しくなるWebIDE ツール)経由でFirefox OSシミュレーター上でのテストをする事ができます。これにより、実際の機器でどのように見えるかという現実的なアイデアを示してくれます。やる事は以下の通りです。
- Firefox OS simulator をインストールする
- App Managerを開く (ツール > Web 開発 > アプリマネージャ )
- すでにインストールされたシミュレータを選択してシミュレータをスタートする
- パッケージアプリの追加をクリックし、ローカルディレクトリのアプリを選択する
- Firefox OS Simulatorにアプリをインストールするためにアプリの更新ボタンをクリックする
Firefox OS 実機でテストする
いままで示してきた方法では、バイブレーションAPIは動作しません。完全なテストをしたい場合は、Firefox OSの実機を手に入れる必要があります。もし入手したら、コンピュータと接続し、App Manager経由でローカルドライブにあるアプリをインストールする事ができます。実際に動かしてみたとき(システム通知も一緒に)のスクリーンショットは以下の通りです。
Firefox OS実機にApp Manager経由でアプリをインストールする手順:
- Firefox OS simulatorとADB helperをインストールする
- App Managerを開く( ツール > Web 開発 > アプリマネージャ)
- Firefox OS 実機上で、ADBと開発者オプションを選択肢、開発者向けリモートでバッグ設定にする
- 端末とデスクトップPCをUSBで接続する
- App Managerの下の方の"未接続"バーに接続したデバイスを示すオプションが表示されるのでクリックする。例えばギークスフォンのKeonは常に
full_keon
と表示される。 - パッケージアプリの追加をクリックし、ローカルディレクトリのアプリを選択する
- Firefox OSの実機にアプリをインストールするためにアプリの更新ボタンをクリックする
アプリの提出と配布
これでアプリは作成できました。これで一般的なWebサイトやアプリ(より詳しい情報はアプリ配布オプションを読んでください。)、自己配布パッケージアプリのようにサーバー上に配置したり、Forefox Marketplaceに提出することができます。手順はあなたの事情によりかわってきます。
- Firefox OS アプリを公開するとき、一般的に一パッケージアプリとして利用可能にする事がよいアイデアです。パッケージ化されたアプリは特権APIへのアクセス(アプリパーミッションをご覧ください)という利点があり、デバイスがオフラインでもインストールすることができます。パッケージ化されたアプリはすでに述べた通り、無料で効果的にアプリキャッシュ機能を利用でき、また既に述べた通りインストールされた機能を削除する事も可能です(この方法の変わりとしての情報は Self-publishing pakcaged apps を参照してください)
- もし、Firefox OS アプリではなく単なるWebアプリとして入手可能にしたい場合は、この記事で述べている通り、サーバー上にアップロードすればよいです。
Makertplaceに提出する際に、アプリのmanifestは検証され、あなたのサポート対象とするデバイスを選択する必要があります(Firefox OS, デスクトップ版Firefox, モバイル版Firefox, Firefox Tablet)。検証されたあと、アプリの詳細情報(スクリーンショット、説明、値段、その他)を追加し、正式にMaketplaceにリスト化されるために提出します。承認された後、全世界からアプリが購入・インストールする事ができるようになります。
さらなる情報
以上ですべてですが、クイックスタートは明らかにアプリ開発をするための情報がとても単純に書かれていました。しかし、必要となる新しいすべての情報を効果的に学ぶことを目的としてたためこの方法をとってきました。アプリ開発、設計、Firefox OSの異なる面についての詳しい上は以下のリソースにアクセスしてください。
Firefox OS
Firefox OS ゾーンでは、プラットフォームのビルド方法や、Gaiaプロジェクトへの寄与、デバイス仕様、Forefox OS仕様とテストテクニックなどFirefox OS プラットフォームに焦点をあてています。
アプリ設計
ユーザーインターフェイスの設計に正解はありませんが、あなたのアプリをより楽しく使いやすくする方法はいくつもあります。アプリ設計セクションでは、共通のUI間違いを防ぐ事を助けたり、動作しているプラットフォームに依存しないレスポンシブデザインやアプリを利用しやすくするための設計エッセンスを提供します。
アプリ構築
アプリ構築セクションでは、新規開発者への推奨情報や開発者共通の問題への対処方法を、問題を経験した開発者がアドバイスしたり、チュートリアルやより理解するためのAPIリファレンスのリストなどが提供されています。
アプリ公開
アプリ公開とユーザーベース形成を開始したいですか? Marketplaceゾーンには、あなたが必要な公開オプションやFirefox Marketplaceへの提出方法、支払いハンドリングなどの情報が含まれます。
FAQ
定期的にアプリ開発の基本的なことで質問される内容
フレームワーク/ライブラリを利用すべきか?
もしあなたのワークフローで頻繁に利用している傾向があり、すでに持っているのであれば、インストール可能オープンWebアプリで利用してはいけない理由はありません。
利用可能なサンプルアプリはどこにありますか?
MDN App Centerにはたくさん入手可能なアプリがあります。