Getting Started with Firefox OS: Hosted and Packaged Apps

Jeff Friesen
This entry is part 2 of 2 in the series Getting Started with Firefox OS

Getting Started with Firefox OS

Mozilla’s Firefox OS runs Web apps instead of native apps. In Part 1 of my two-part series on getting started with this mobile operating system, I introduced Firefox OS and discussed setting up an environment for developing Web apps.

This article ends the series by introducing you to hosted and packaged apps, which are the two Web app categories supported by Firefox OS. I show you how to create each kind of app, and how to distribute the app via Firefox OS Marketplace.

Discovering Hosted Apps

Firefox OS supports hosted apps, which are websites turned into Web apps — the website is the app. Millions of websites already exist that can be easily turned into hosted apps, giving Firefox OS an exceptional competitive advantage.

Creating a Hosted App

Creating a hosted app is easy. From the dashboard, enter a website’s URL and click the Add URL button. For example, I entered my TutorTutor website’s http://tutortutor.ca URL, as shown in Figure 1.

 Enter a URL and click Add URL.

Figure 1: Enter a URL and click Add URL.

In response to clicking Add URL, the simulator starts running and displays part of my website’s main page — see Figure 2.

Drag the mouse over the simulator screen to view more of this Web page

Figure 2: Drag the mouse over the simulator screen to view more of this Web page.

The dashboard creates a manifest file (discussed shortly) with default values and then validates it. According to Figure 2, validation resulted in a single warning message:

app submission to the Marketplace needs at least an 128 icon

The error message refers to my not having specified an icon for this app. Firefox OS Marketplace requires a submitted app to have a minimum of one icon whose dimensions are at least 128-by-128 pixels.

In the absence of an icon, the dashboard creates a default application icon for the home screen. When creating the app shown in Figure 2, the dashboard obtained this icon from my website’s favicon.ico file and scaled it up, as shown in Figure 3.

 An application icon based on favicon.ico was generated for tutortutor.ca.

Figure 3: An application icon based on favicon.ico was generated for tutortutor.ca.

Every hosted and packaged app requires a manifest, a JSON file named manifest.webapp. The manifest provides information about the app such as version, name, description, icon location, and locale strings. The dashboard creates a manifest when it isn’t specified.

For example, Listing 1 presents a simple manifest.webapp file that describes my website’s Aquarium page as a hosted app.

{
  "name": "Aquarium",
  "description": "Observe several swimming fish.",
  "launch_path": "/cgi-bin/makepage.cgi?/software/Aquarium"
}

Listing 1: The name and description fields are required for hosted and packaged apps.

The name field identifies the app’s name, which is displayed on the simulator. The description field describes the app and has a maximum length of 1024 characters. The launch_path field identifies the location of the Web resource to be loaded.

Note
To learn more about the app manifest, check out Mozilla’s App manifest and FAQs about app manifests documentation.

I uploaded this manifest.webapp file to my website’s root directory. However, before I could use the dashboard to add this app, I had to add the following MIME type to my Web server and associate it with the .webapp file extension:

application/x-web-app-manifest+json

App manifests must be served with a Content-Type header of application/x-web-app-manifest+json. Although not currently enforced by Firefox, it is enforced by Firefox OS Marketplace.

After accomplishing this task, I entered http://tutortutor.ca/manifest.webapp into the dashboard — see Figure 4.

Enter a manifest URL and click Add Manifest

Figure 4: Enter a manifest URL and click Add Manifest.

In response to clicking Add Manifest, the simulator starts running and displays part of my website’s Aquarium page — see Figure 5.

rag the mouse over the simulator screen to view more of the aquarium

Figure 5: Drag the mouse over the simulator screen to view more of the aquarium.

The dashboard validates the manifest, resulting in a “Missing 'icons' in Manifest.” warning message because I didn’t specify an icons field in the manifest. As a result, the dashboard chooses a default icon (there is no favicon.ico file in the launch path) — see Figure 6.

A default application icon is generated for Aquarium

Figure 6: A default application icon is generated for Aquarium.

This app should have its own icon. According to the Firefox OS app icons page, the application icon is a 60-by-60-pixel image provided in 24-bit PNG format.

This page provides a list of do’s and don’ts, examples, and templates for creating your icons. I chose a blue rounded circle template along with a PNG-based overlay, created a small rectangular thumbnail image of an aquarium, and combined these images via an online tool.

Continuing, I named this file 60.png, created an /icons directory on my Web server, and uploaded this file to that directory. Then, I modified the manifest.webapp file to look as follows, and uploaded it to my Web server’s root directory:

{
  "name": "Aquarium",
  "description": "Observe several swimming fish.",
  "launch_path": "/cgi-bin/makepage.cgi?/software/Aquarium",
  "icons": 
  { 
    "60":  "/icons/60.png"
  }
}

I started the simulator and observed the new icon on the home screen that’s shown in Figure 7.

My app icon consists of a rectangular aquarium image over a circle background

Figure 7: My app icon consists of a rectangular aquarium image over a circle background.

Distributing a Hosted App

After creating a hosted app, you’ll want to distribute it, most likely through Firefox OS Marketplace. In this section, I’ll walk you this process, starting with steps for completing the app.

Firefox OS Marketplace requires that your app have at least a single icon, whose dimensions are at least 128-by-128 pixels. Therefore, you should create this icon and store it in an appropriate location on your Web server (and update manifest.webapp, appropriately).

There are a few other fields that you might want to specify in the manifest. For example, you might want to specify developer and version fields. Listing 2 shows you my final manifest file for the Aquarium app.

{
  "name": "Aquarium",
  "description": "Observe several swimming fish.",
  "version": "1.0",
  "launch_path": "/cgi-bin/makepage.cgi?/software/Aquarium",
  "developer": 
  { 
    "name": "Jeff Friesen", 
    "url": "http://tutortutor.ca" 
  }, 
  "icons": 
  { 
    "128": "/icons/128.png",
    "60":  "/icons/60.png"
  }
}

Listing 2: I’ve added developer and version information to this manifest.

My final manifest references two icons. The 128-by-128-pixel icon in 128.png is used by Firefox OS Marketplace when presenting the app, and the 60-by-60-pixel icon in 60.png appears on the simulator home screen as the app icon.

Another item to consider is what the user will initially see when clicking the Aquarium icon. Figure 8 shows you that the aquarium shown in Figure 5 is not what the user initially sees.

The user doesn't initially see the aquarium with swimming fish. The page must be dragged until the aquarium is in view

Figure 8: The user doesn’t initially see the aquarium with swimming fish. The page must be dragged until the aquarium is in view.

I created my website before smartphones and tablets became widespread and haven’t yet redesigned this site to make it mobile friendly. I could use media queries and responsive design for this task.

Note
Mozilla provides extensive documentation on responsive design.

After completing your app, you can submit it to Firefox OS Marketplace. Begin by pointing your browser to the submission page and log in with your free Persona account.

You need to log in via your free Persona account

Figure 9: You need to log in via your free Persona account.

After signing in, choose a device type, which would be Firefox OS, and enter the app manifest URL — see Figure 10.

Choose the Firefox OS device type and enter the app's manifest URL.

Figure 10: Choose the Firefox OS device type and enter the app’s manifest URL.

The marketplace attempts to validate the app. When it reports validation successful, click the Continue button to fill out app details — see Figure 11.

The screen displays my 128-by-128-pixel icon. The description is taken from the manifest's description field

Figure 11: The screen displays my 128-by-128-pixel icon. The description is taken from the manifest’s description field.

I’m not going to proceed because I don’t feel that Aquarium is ready for publication — I should employ responsive design to provide a better viewing experience when the user is taken to the page.

Discovering Packaged Apps

Firefox OS also supports packaged apps, which are Zip files containing all app assests: HTML, CSS, JavaScript, images, manifests, and so on. Unlike hosted apps, they are downloaded onto the device.

Packaged apps can access sensitive APIs and must be verified by the stores where they’re distributed. A store reviews the app and, if acceptable, signs the Zip file with the app’s private key, assuring the app’s users that the app has been reviewed for security and other issues.

There are three kinds of packaged apps:

  • Privileged: A privileged app is approved by the Firefox OS Marketplace via a special process. It provides more safety for users when an app wants access to certain sensitive APIs on a device, and is equivalent to a native app on a platform such as iOS or Android.
  • Certified: A certified app is intended for a critical system function (e.g., a smartphone’s default dialer or system settings app). It’s used for critical functions on a Firefox OS phone, and isn’t intended for third-party apps — most app developers can disregard certified apps.
  • Plain Packaged: A plain packaged app is a regular packaged app. It cannot use certain sensitive Web APIs. Firefox OS Marketplace signs it, but doesn’t perform the special authentication process used for privileged or certified apps.

For more information on packaged apps (and especially how they differ from hosted apps), check out Mozilla’s Packaged Apps document.

Creating a Packaged App

Creating a packaged app is also easy. To begin, you should set up a simple file and directory structure. For example, I created the following file and directory structure for a packaged app that obtains and displays the current geographic location:

icons
   60.png
   128.png
js
   app.js
   jquery-1.10.1.min.js
index.html
manifest.webapp

Listing 3 presents the contents of index.html.

<!DOCTYPE html>
  <html>
    <head>
      <title>Where am I?</title>
      <script src="js/jquery-1.10.1.min.js"></script> 
      <script src="js/app.js"></script>
      <style>
      @media (orientation: landscape)
      {
         #map { float: right }
         #left { float: left }
      }
      </style>
    </head> 

    <body>
      <div id="left">
      <button id="whereami">
        Where am I?
      </button>

      <p>
      Geolocation coordinates:

      <p>
      <span id="latitude"></span>

      <p>
      <span id="longitude"></span>
      </div>

      <p>
      <div id="map">
      </div>
    </body> 
  </html>

Listing 3: The index.html file is the app’s starting point.

Listing 3 describes the HTML that drives the app. The header includes a title (which a Firefox OS device may or may not use), a script tag that imports jQuery, a script tag that imports the app’s JavaScript logic, and a style tag (discussed shortly).

The app displays a button, followed by a Geolocation coordinates: label, followed by a couple of spans for displaying latitude and longitude, followed by a div for presenting a map image of the current location. These user-interface elements look okay in portrait mode.

In landscape mode, most of the map is cut off and there is excessive whitespace on the right. To improve the user interface, I’ve added a style tag whose media query floats the elements over the screen when the device is in landscape mode.

Listing 4 presents the contents of app.js.

$(function() 
{
   if (!("geolocation" in navigator))
   {
      $("#latitude").text("geolocation not available");
      return;
   }

   function getGeoData()
   {
      function success(position)
      {
         var latitude = position.coords.latitude;
         var longitude = position.coords.longitude;
         $("#latitude").text("Latitude: "+latitude);
         $("#longitude").text("Longitude: "+longitude);
         var img = new Image();
         img.src = "http://maps.googleapis.com/maps/api/staticmap?center="+
                   latitude+","+longitude+"&zoom=13&size=300x300&sensor=false";
         var node = document.getElementById("map");
         node.removeChild(node.firstChild);
         node.appendChild(img);
      }

      function error(err) 
      {
         $("#latitude").text("unavailable");
      }

      navigator.geolocation.getCurrentPosition(success, error);
   }

   $("#whereami").click(getGeoData);
});

Listing 4: The app.js file defines the app’s logic.

Listing 4 checks that the navigator.geolocation property exists, outputting a geolocation not available message when this property doesn’t exist. Also, it registers a click handler with the whereami button to invoke getGeoData() when the button is clicked.

The getGeoData() function first defines success() and error() functions to be called when the location can be obtained or not (perhaps the user doesn’t give permission). It then executes navigator.geolocation.getCurrentPosition(success, error);.

The user is asked to grant/deny permission. When granted and nothing goes wrong, success() is called with a position argument whose latitude and longitude are extracted and displayed. Also, a Google-based map for this position is obtained and displayed.

Listing 5 presents the contents of manifest.webapp.

{ 
  "name": "Where am I?", 
  "description": "This app tells you where you're located.",
  "version": "1.0",
  "launch_path": "/index.html", 
  "developer": 
  { 
    "name": "Jeff Friesen", 
    "url": "http://tutortutor.ca" 
  }, 
  "icons": 
  { 
    "128": "/icons/128.png",
    "60":  "/icons/60.png"
  }, 
  "permissions": 
  {
    "geolocation": 
    {
      "description": "Needed to tell the user where they are"
    }
  }
}

Listing 5: Permission is needed to access the Geolocation API.

An app needs permission to access the Geolocation API. The name of this permission is geolocation, and it must appear as a subfield of a permissions field.

Note
Mozilla’s App permissions document describes geolocation and also provides a complete list of permissions.

Figure 12 shows the app running in portrait mode.

The 'Where am I?' app in portrait mode.

Figure 12: The ‘Where am I?’ app in portrait mode.

Figure 13 shows the app running in landscape mode.

The 'Where am I?' app in landscape mode

Figure 13: The ‘Where am I?’ app in landscape mode.

Distributing a Packaged App

Before you can distribute a packaged app, you need to zip its file and directory structure into a Zip archive. For example, I archived ‘Where am I?’s file and directory structure (repeated below) into whereami.zip:

icons
   60.png
   128.png
js
   app.js
   jquery-1.10.1.min.js
index.html
manifest.webapp

You can now submit this packaged app to Firefox OS Marketplace. As when submitting a hosted app, point your browser to the submission page and log in with your free Persona account.

fter signing in, choose a device type, which would be Firefox OS. Then, click the Packaged tab, click the subsequent Select a file… button, and select the packaged app’s Zip file — see Figure 14.

The Zip file is automatically validated.

Figure 14: The Zip file is automatically validated.

Click the Continue button and fill out app details on the resulting page. After filling out these details, click the Continue button again to have the app reviewed.

Conclusion

I’ve introduced hosted and packaged apps, and have shown you how to create and distribute each kind of Web app. To learn more about Firefox OS and app development, check out Mozilla’s extensive documentation at the following sites:

Firefox OS’s focus on Web apps makes it an interesting alternative to Android, iOS, and other native-app-oriented mobile operating systems. With Firefox OS starting to gain momentum, now is a great time to start writing (and eventually monetizing) Web apps for this platform.

Getting Started with Firefox OS

<< Getting Started with Firefox OS

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Ari Ogoke

    Hi Jeff,

    Except for the @media CSS style, the code you supplied the packaged app looks like a “regular” web app code. (I guess that is what Mozilla was shooting for.)

    Anyway, after commenting out the CSS style, I ran the code on my desktop but the JS didn’t kick in when I pressed the button. Did I miss something?

    The 2 Javascript files are in the correct directories. ( I see that jQuery takes advantage of the elements in the HTML source code.)

    Thanks.

    Ari

    • http://tutortutor.ca Jeff Friesen

      Hi Ari,

      I find the @media style helpful for optimizing screen space when switching between portrait and landscape modes.

      I assume that you are referring to the “Where am I?” button. When I click this button, I’m taken to a permission screen with Deny and Allow buttons. Clicking Allow causes the coordinates to be obtained and displayed along with a corresponding Google map.

      Feel free to email me and I’ll send you the whereami.zip file that I used for testing — I know this file works on my platform. I can also go over step-by-step instructions to help you get it working on yours.

      All the best.

      Jeff

  • Ari Ogoke

    Thanks, Jeff!

    Yes, clicking the “Where am I?” button did not produced the desired effect. I have reviewed my code several times to make sure I reproduced your faithfully. (My platform supports geolocation.)

    I sent you an e-mail message.

    Ari
    P.S.
    I understand the purpose of the @media CSS styles. I disabled it because I was running the code on a desktop. (I know it wouldn’t have hurt to leave it there.)

  • Ari Ogoke

    Hi Jeff,

    Thank you for the files. I want to confirm that your app worked on my computer. It took a while but Turns out that I named the Javascript file “appS.js” instead of “app.js”.

    Thanks again!!!

    BTW, love your tutorial! Firefox OS may not be able to run with the big boys immediately but it WILL change the way mobile apps are created and distributed.

    Thanks for taking the time to share!!!

    Ari

    • http://tutortutor.ca Jeff Friesen

      Hi Ari,

      That’s excellent. I’m glad it worked out for you.

      All the best.

      Jeff