//TNG The Nitty Gritty

The low down on web technology

Building Apps For Firefox OS, Chrome OS And The Web

by Addy Osmani

Firefox OS mobile apps

I was speaking at Web Rebels two weeks ago, where the Firefox OS team were kind enough to give me a new Geekphone Peak device, so I dove right into building some apps for it. Obligatory unboxing pics below!

FFOS unboxing
Firefox OS unboxing
ffox_r1_c1
Authenticate yourself via Github
ffox_r2_c1
Repositories overview and repo editing

I've enjoyed building Chrome apps and packaged apps before and am always interested in experimenting with new projects that build upon the web platform. They give us an opportunity to demonstrate that just using the primitives granted by HTML, CSS and JavaScript we have the potential to deliver compelling experiences that can strive to complete against native desktop and mobile apps. In this regard, Firefox OS is quite interesting.

My first idea for a Firefox OS app was a simple AngularJS Github issues viewer (based on ng-github-client) with views for authentication, a dashboard and info editing amongst others. This is a simple enough app, but as it handles authentication and relies on a real data source I figured it might be a more realistic base than a todo app ;)

Firefox OS exposes some additional APIs on devices, so I thought it might be interesting to try adding support for the Vibration API, Web Activities and Web Notifications. These would let me share (activities), alert on error (device vibrate, alarm) and inform me when a connection was no longer available (notifications).

As you can see below, talking to the Vibration API is quite straight forward.

// Vibration
var vibrate = document.querySelector("#vibrate");
if (vibrate) {
    vibrate.onclick = function () {
        var vibrating =
navigator.vibrate(2000);
        /*
            Possible values:

            On/off pattern:


navigator.vibrate([200, 100, 200, 100]);

            Turn off vibration


navigator.vibrate(0);
*/
};
}

At this point I must say – setting up much of this was massively simplified thanks to the great work Robert Nyman has done on the Firefox OS boilerplate.

Untitled-3_r1_c1
The Firefox OS boilerplate comes with some great presets to make your life easier

Robert's boilerplate includes complete code snippets for many of the common tasks you might want to use such APIs for and would actually love to see us do something similar for a boilerplate for Chrome apps. It also includes boilerplate manifest.webapp files, and you may find the online validator for these useful if heavily modifying for your own needs.

ffos-yo
Firefox OS + Yeoman = ♥

I kickstarted off my app using Yeoman and the Firefox OS generator which serves up Robert's boilerplate via the command-line.

To get this setup install Yeoman:

npm install -g yo

Install this generator:

npm install -g generator-firefox-os

And run:

yo firefox-os

If you don't want to use the boilerplate or Yeoman to create your app, you can get started with a Firefox OS app in just a few steps:

  1. Create a new directory called myapp
  2. Create a new HTML file in this directory (e.g index.html)
  3. Tools → Web Developer → Responsive Design View in Firefox will let you preview the app using some mobile sizes
  4. Create a `manifest.webapp file with some name, permissions details
  5. Tools → Web Developer → Firefox OS simulator (when installed), click "add directory" and then just select your manifest.webapp
  6. You should be able to see the app you created
  7. Once your app is finished, just upload it to a server (or GitHub pages) and share the link

Here is a pretty straightforward example manifest.webapp file for the app:

{
    "version": "1.0.0",
    "name": "GitHub Issues Viewer",
    "launch_path": "/GitHub-Issues-Viewer/index.html",
    "description": "A GitHub Issues Viewer for Firefox OS",
    "icons": {
        "128": "/GitHub-Issues-Viewer/img/icon-128.png"
    },
    "developer": {
        "name": "Addy Osmani",
        "url": "http://addyosmani.com/"
    },
    "installs_allowed_from": ["*"],
    "default_locale": "en"
}

Not everyone agrees with me, but I look at Firefox OS and Chrome OS as enhanced build targets. My personal approach with them is to build a web app so that it can work fine in any browser and then progressively enhance it using feature detection for the enhanced APIs you'd like to take advantage of. This is sometimes easier said than done, but does mean that you treat these platforms as build targets and don't have to treat them as entirely different apps. If you're using Grunt for your task/build process, just setup your FFOS app as a second build target and include your manifest files/additional scripts. grunt-env and grunt-preprocess can be useful here. QuickOffice (part of the Google Docs team) do something similar for their Chrome app, which also gets deployed as a PhoneGap app for other platforms.

Debugging in Firefox OS

overview
Debugging in Firefox OS

Next, onto debugging. I installed the Firefox OS simulator which lets you preview what your app might look like on a device and also detects whether an FFOS device is connected so you can remotely debug using their developer tools. The simulator is extremely straight-forward to use, allowing you to preview apps hosted remotely/your own server or simply those being worked on on the local filesystem. You also have access to a detailed error console, for keeping an eye on general exceptions and errors about unsupported APIs.

The "Push" to device button also made it a breeze to switch between the Geekphone and Simulator at any time.

Note that Mozilla's documentation is forward about the limitations of the simulator - for APIs that aren't available on desktop (vibration, telephony), you may find yourself having to throw/log your own debug errors. I personally also found that my app appeared visually different in the simulator than it did when I deployed to my Geekphone device. As a developer preview, I found the changes minimal enough to not be distruptive but I plan on investigating further/reporting bugs if it's not simply an issue with the boilerplate.

Some other minor problems I ran into:

I was impressed that for performance profiling, Firefox OS makes paint flashing and an FPS counter just a few quick touches away, making it simple to debug and check where you might be experiencing issues.

I did find myself having to go back to the Chrome DevTools for more granular profiling needs but flipping between browsers and tools didn't really slow me down that much. For the process of actually deploying an app, Chris Lord's writing/deployment guide was helpful as was this blog post.

Great, so building a simple application that works on Firefox OS based on the boilerplate isn't massively difficult and as with any platform just takes a little time to get used to. I actually really enjoyed writing IssueHub. Some more screenshots of it can be found below.

Building Apps For Multiple Browsers

The next thing I wanted to set out to do was see if I could build an app that worked everywhere, so in any modern browser but also as a Chrome app and Firefox OS app. For this, I used the already well-developed TimerX3 web app, which was built using Yeoman, Grunt and Bower:

timerapp
The TimerX3 app

TimerX3 let's you install from the web if it's supported (FFOS only), uses Firefox OS-specific APIs but also works fine in other browsers with a slightly degraded experience (no vibration etc). Adjusting the codebase for this app so that I could get some of the same enhanced features available to FFOS users (e.g notifications) involved a few steps:

Screen Shot 2013-05-25 at 22.55.11
about:extensions

You can easily check if APIs are actually supported by one browser only. For example with the Vibration API it could look something like this:

// Use native API or fallback for unsupported browsers
navigator.vibrate = navigator.vibrate || navigator.mozVibrate || function (vibrate) {
    console.log('vibrate not supported', vibrate);
};

// Call the Vigration API
navigator.vibrate([200, 100, 200, 100]);
Screen Shot 2013-05-25 at 23.30.27
TimerX3 inline-installed in Chrome

Once this looks good, you can add your Chrome app as a second/third build target to your Gruntfile and just specify those additional files (e.g manifest.json etc) you want to build into their own target. This way you end up with three builds – one for your standard webapp, one for your Firefox OS app and another for your Chrome app all of which can be offered up to your users via the web or dedicated app stores. For those interested, I'm including screenshots of the TimerX3 app working across all of the build targets I was hacking away at.

apps
TimerX3 working across all of the build targets
Photo 2013-05-26 02.47.36 PM

Multiple build targets with Grunt

In order to set up your multiple build targets I would recommend reading this Stackoverflow answer and using grunt-env, grunt-preprocess and optionally grunt-replace.

Conclusion

I'll post the code to GitHub at some point once I get a chance to clean it up, but all in all I enjoyed my experience building both an app that worked on Firefox OS and extending another to work everywhere.

Right now the biggest thing I think the FFOS ecosystem needs is improved documentation. The getting started experience is fantastic, but beyond that an increase in tutorials walking developers through creating apps of different complexity would be welcome.

I know a few developers have asked me if the Simulator on it's own is "enough" for creating a fully-functional app - my honest answer is that for most enhanced APIs, you can get really far with it. Test out the boilerplate by Robert if you need proof of that. If you're intending on deploying an app that uses features the simulator can't handle however, I recommend mocking them during development and then trying to get a loaner device from a local device lab if one is available.

blog comments powered by Disqus