MOBILE

Programming the Mobile Web : HTML 5 (part 4) - Client Storage

1/24/2011 4:28:02 PM

7. Client Storage

Working offline is great, but there’s a problem: where should a web application store vital statistics and other information when the device is not connected to the Internet? And if the device is not connected to the Internet, how can our applications access helpful databases or information? Client storage solutions come to our assistance, in two flavors: key/value storage and SQL databases (yes, from JavaScript, without server interaction).

Of course, we also have cookies, but they are simpler (only string storage), and we know they are not guaranteed to survive in the browser.

7.1. Key/value storage

HTML 5 defines a key/value store through two objects: localStorage and sessionStorage. They are pretty much the same, but the scopes are different: while the local store is used for long-term storage, the session store doesn’t persist after the user closes the tab or window.


Note:

We should use try/catch blocks when saving items, in case problems occur with the storage or the maximum available space is exceeded.


Both stores are used in the same way:

// Save an object or variable in the store
localStorage.setItem("name_in_the_storage", object_to_store);

// Read an object from the store
var object = localStorage.getItem("name_in_the_storage");

We can also delete all the objects using clear or delete one key using removeItem. There is also a storage event that we can listen for with window.addEventListener that will be fired when the contents of the local or session stores have changed.

7.2. SQL database

Having a relational database available in JavaScript sounds powerful. The main method that defines the availability of the JavaScript SQL database is the window.openDatabase method. This method has the following signature:

var db = window.openDatabase(shortName, version, displayName, sizeExpectable);

If we use a try/catch, we can capture errors during the operation. This method opens the database if it exists and creates it if it is the first time we’ve used it. To execute non-recordset sentences (CREATE TABLE, INSERT, etc.) we can use a transaction using the transact method, which receives a function as parameter. As a transaction, if one sentence fails, the others will not execute:
db.transact(function(t)) {
t.executeSql('CREATE TABLE countries (id INTEGER NOT NULL PRIMARY KEY
AUTOINCREMENT, name TEXT NOT NULL)', [], function() {}, errorHandler);
});

The array parameter after the query string is an array of parameters to be replaced in the query (using ? inside), the next parameter is the data handler function (not used in a non-recordset query), and the last parameter is a function handler for errors in the query.


Note:

HTML 5 doesn’t define which database engine should be used. Mobile browsers use SQLite, the open source database engine, so check the SQLite documentation for data type and SQL syntax support.


To create a typical SELECT statement with recordset looping, we can use the following template:

db.transact(function(t)) {
t.executeSql('SELECT * FROM countries', [], countriesHandler, errorHandler);
});

function countriesHandler(transaction, data) {
var record;
var id;
var name;
for (var i=0; i<data.rows.length; i++) {
// We get the current record
record = data.rows[i];
id = record['id'];
name = record['name'];
// Do something with record information
}
}

function errorHandler(transaction, error) {
alert('Error getting results');
}



Note:

JavaScript databases support versioning, allowing us to change schema on newer versions of our applications and detect what the current version installed on the client is, to create a migration procedure.


If you were working offline you should implement a synchronization method, using Ajax to download changes from and upload them to the server.


Note:

Safari on iOS accepts up to 5 MB in offline storage without user intervention. If you try to save more than 5 MB, the user will need to approve it (an automatic alert will appear).


7.2.1. Gears storage

Google Gears (http://code.google.com/apis/gears) is an open source project that enhances web browsers and JavaScript with more functionality, much of which is part of the HTML 5 draft. Android 1.X supports only Gears, and we can also use SQL databases with Gears. The normal usage is simple and synchronous, as the following sample demonstrates:

<script type="text/javascript" src="gears_init.js"></script>
<script type="text/javascript">
var db = google.gears.factory.create('beta.database');
db.open('countries');
db.execute(CREATE TABLE countries (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL)');

var rs = db.execute('SELECT * FROM countries');

while (rs.isValidRow()) {
var id = rs.field(0);
var name = rs.field(1));
// Do something
rs.next();
}
rs.close();
</script>

Fortunately, Google is working on an open source project that gives us an abstraction layer for both HTML 5 databases and Gears databases using the same code. The project is called the Web Storage Portability Layer and it is available at http://code.google.com/p/webstorageportabilitylayer.

Note:

Safari on iOS allows you to view stored databases and delete them from the device using SettingsSafariDatabases.


With this new layer, we can use the following code for select queries in both frameworks:

var database = google.wspl.DatabaseFactory.createDatabase('countries',
'http://yourdomain/dbworker.js');
var statement = google.wspl.Statement('SELECT * FROM countries;');

database.createTransaction(function(tx) {
tx.executeAll([statement], {onSuccess: function(tx, resultSet) {
// Statement succeeded

for(; resultSet.isValidRow(); resultSet.next()) {
var id = resultSet.getRow()['id'];
var name = resultSet.getRow()['name'];
}
}, onFailure: function(error) {
// Statement failed
}});
}, {onSuccess: function() {
// After transaction commits, before any other starts
}, onFailure: function(error) {
// After transaction fails, before any other starts
}});

7.3. Client JSON store

Prepared for mobile devices, Lawnchair is a local client JSON store that uses HTML 5 features behind a very simple API. You can download the library from http://brianleroux.github.com/lawnchair.

To create a store, we just use code like this:

var countries = new Lawnhair('countries');

Then, we can save an object synchronously:

countries.save({id: 5, name: 'Spain'});
// Object saved

or asynchronously:

countries.save({id: 5, name: 'Spain'}, function() {
// Object saved
});

We can also save it using a key/value mechanism for easy retrieval:

countries.save({key: 5, value: 'Spain'});

var spain = countries.get(5);

And we can easily get all the documents using:

countries.all(function(country) {
// We receive every country in this function
});

We can also remove documents, clear all the storage, and create iterators for easy filtering.

Web Compatibility Test

In 2010, the W3C created a test to score mobile browsers in terms of their RIA, Ajax, and HTML 5 support. The Web Compatibility Test for Mobile Browsers, available at http://www.w3.org/2010/01/wctmb2, verifies compatibility with Ajax, the canvas HTML tag, the contenteditablevideo and audio HTML 5 tags, Web Workers, local storage, session storage, and @font-face. There are currently no mobile browsers that score 100%. attribute, geolocation, HTML 5 input forms, the offline AppCache, the

Some results are:

  • iPhone 3.0: 83%

  • Firefox 3.5 for Maemo: 83%

  • Bada Browser: 75%

  • Android 1.6–2.1: 67%

  • Opera: 33%

  • Symbian 5th edition: 17%

  • webOS: 17%

  • NetFront 3.5: 8.33%


Other  
  •  Windows Phone 7 : Submitting Your First Windows Phone Application to the Windows Phone Marketplace
  •  Windows Phone 7 : Packaging, Publishing, and Managing Applications
  •  Mobile Application Security : Windows Mobile Security - Development and Security Testing (part 3)
  •  Mobile Application Security : Windows Mobile Security - Development and Security Testing (part 2)
  •  Mobile Application Security : Windows Mobile Security - Development and Security Testing (part 1)
  •  Programming the Mobile Web : Mobile Rich Internet Applications (part 2) - JavaScript Mobile UI Patterns
  •  Programming the Mobile Web : Mobile Rich Internet Applications (part 1) - JavaScript UI Libraries
  •  Windows Mobile Security - Kernel Architecture
  •  Windows Mobile Security - Introduction to the Platform
  •  iPhone Programming : Table-View-Based Applications - Building a Model
  •  
    Most View
    Expert Computing Advice – January 2013 (Part 1)
    How To Find The BEST DEALS (Part 1)
    Chillblast Fusion Sentry - A Fast PC Kitted Out With One Of Intel’s Latest Processors
    The Great In-App Purchase Rip-Off (Part 1)
    One For All And All In One (Part 1) - Asus ET2701INKI-B046C
    Z/28 Versus M6 Versus GT-R – The Monster Battle (Part 2)
    Installing and Configuring SharePoint 2013 : Creating the Farm (part 7) - Configuring the App Management Service - Configuring the User Profile Service
    Toshiba STOR.E Edition 500GB
    Installing and Configuring SharePoint 2013 : Creating Web Applications and More
    Windows 8 : Customizing the Appearance of Windows - Changing the Desktop Color Scheme - Change Windows Color and Transparency
    Top 10
    The Nissan GT-R Nismo – The Fastest And Most Powerful Version Of The Nissan GT-R (Part 4)
    The Nissan GT-R Nismo – The Fastest And Most Powerful Version Of The Nissan GT-R (Part 3)
    The Nissan GT-R Nismo – The Fastest And Most Powerful Version Of The Nissan GT-R (Part 2)
    The Nissan GT-R Nismo – The Fastest And Most Powerful Version Of The Nissan GT-R (Part 1)
    Personal Electronics, Tech For Home & Leisure
    Second Gear - Samsung Gear 2 (Part 2)
    Second Gear - Samsung Gear 2 (Part 1)
    Techdesk Most Wanted 9_2014
    The A_List Game Box
    Two Is Better Than One - WD My Cloud Mirror