Firefox OS/Pinned Apps
Pinned Apps - An app model for the web
Problem Statement
The per-OS app store model has resulted in a market where a small number of OS companies have a large amount of control, limiting choice for users and app developers. In order to get things done on mobile devices users are restricted to using apps from a single app store which have to be downloaded and installed on a compatible device in order to be useful.
Design Concept
Concept Overview
The idea of pinned apps is to turn the apps model on its head by making apps something you discover simply by searching and browsing the web. Web apps do not have to be installed in order to be useful, “pinning” is an optional step where the user can choose to split an app off from the rest of the web to persist it on their device and use it separately from the browser.
If you think of the current app store experience as consumers going to a grocery store to buy packaged goods off a shelf, the web is more like a hunter-gatherer exploring a forest and discovering new tools and supplies along their journey.
App Discovery
A Web App Manifest linked from a web page says “I am part of a web app you can use separately from the browser”. Users can discover web apps simply by searching or browsing the web, and use them instantly without needing to install them first.
App discovery could be less like shopping, and more like discovering a new piece of inventory while exploring a new level in a computer game.
App Pinning
If the user finds a web app useful they can choose to split it off from the rest of the web to persist it on their device and use it separately from the browser. Pinned apps can provide a more app-like experience for that part of the web with no browser chrome and get their own icon on the homescreen.
For the user pinning apps becomes like collecting pin badges for all their favourite apps, rather than cluttering their device with apps from an app store that they tried once but turned out not to be useful.
Deep Linking
Once a pinned app is registered as managing its own part of the web (defined by URL scope), any time the user navigates to a URL within that scope, it will open in the app. This allows deep linking to a particular page inside an app and seamlessly linking from one app to another.
The browser is like a catch-all app for pages which don’t belong to a particular pinned app.
Going Offline
Pinning an app could download its contents to the device to make it work offline, by registering a Service Worker for the app's URL scope.
Pinned apps take pinned tabs to the next level by actually persisting an app on the device. An app pin is like an anchor point to tether a collection of web pages to a device.
Multiple Pages
A web app is a collection of web pages dedicated to a particular task. You should be able to have multiple pages of the app open at the same time. Each app could be represented in the task manager as a collection of sheets, pinned together by the app.
Exploding apps out into multiple sheets could really differentiate the Firefox OS user experience from all other mobile app platforms which are limited to one window per app.
Travel Guide
Even in a world without app stores there would still be a need for a curated collection of content. The Marketplace could become less of a grocery store, and more of a crowdsourced travel guide for the web.
If a user discovers an app which isn't yet included in the guide, they could be given the opportunity to submit it. The guide could be curated by the community with descriptions, ratings and tags.
3 Questions
What value (the importance, worth or usefulness of something) does your idea deliver?
The pinned apps concept makes web apps instantly useful by making "installation" optional. It frees users from being tied to a single app store and gives them more choice and control. It makes apps searchable and discoverable like the rest of the web and gives developers the freedom of where to host their apps and how to monetise them. It allows Mozilla to grow a catalogue of apps so large and diverse that no walled garden can compete, by leveraging its user base to discover the apps and its community to curate them.
What technological advantage will your idea deliver and why is this important?
Pinned apps would be implemented with emerging web standards like Web App Manifests and Service Workers which add new layers of functionality to the web to make it a compelling platform for mobile apps. Not just for Firefox OS, but for any user agent which implements the standards.
Why would someone invest time or pay money for this idea?
Users would benefit from a unique new web experience whilst also freeing themselves from vendor lock-in. App developers can reduce their development costs by creating one searchable and discoverable web app for multiple platforms. For Mozilla, pinned apps could leverage the unique properties of the web to differentiate Firefox OS in a way that is difficult for incumbents to follow.
UI Mockups
App Search
Pin App
Pin Page
Multiple Pages
App Directory
Implementation
Web App Manifest
A manifest is linked from a web page with a link relation:
<link rel=”manifest” href=”/manifest.json”>
A manifest can specify an app name, icon, display mode and orientation:
{
"name": "GMail"
"icons": {...},
"display": "standalone",
"orientation": “portrait”,
...
}
There is a proposal for a manifest to be able to specify an app scope:
{ ... "scope": "/" ... }
Service Worker
There is also a proposal to be able to reference a Service Worker from within the manifest:
{ ... service_worker: { src: "app.js", scope: "/" ... }
A Service Worker has an install method which can populate a cache with a web app's resources when it is registered:
this.addEventListener('install', function(event) { event.waitUntil( caches.create('v1').then(function(cache) { return cache.add( '/index.html', '/style.css', '/script.js', '/favicon.ico' ); }, function(error) { console.error('error populating cache ' + error); }; ); });
So that the app can then respond to requests for resources when offline:
this.addEventListener('fetch', function(event) { event.respondWith( caches.match(event.request).catch(function() { return event.default(); }) ); });