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
  •  Mobile Application Security : The Apple iPhone - Push Notifications, Copy/Paste, and Other IPC
  •  Mobile Application Security : The Apple iPhone - Networking
  •  Windows Phone 7 Development : Handling Device Exceptions
  •  Registering a Windows Phone Device for Debugging
  •  Programming the Mobile Web : WebKit CSS Extensions (part 5) - Transformations
  •  Programming the Mobile Web : WebKit CSS Extensions (part 4) - Animations
  •  Programming the Mobile Web : WebKit CSS Extensions (part 3) - Transitions
  •  Programming the Mobile Web : WebKit CSS Extensions (part 2) - Reflection Effects & Masked Images
  •  Programming the Mobile Web : WebKit CSS Extensions (part 1) - WebKit Functions & Gradients
  •  Windows Phone 7 Development : Debugging Application Exceptions (part 2) - Debugging a Web Service Exception
  •  
    Top 10
    Graphics Cards for All Budgets (Part 3) - Radeon HD 7950, GeForce GTX 580, GeForce GTX670
    Graphics Cards for All Budgets (Part 2) - Radeon HD 7770, GeForce GTX 560, Radeon HD 7850, GeForce GTX 660
    Graphics Cards for All Budgets (Part 1) - Radeon HD 6670, GeForce GTS 450, Radeon HD 7750
    Motherboards for All Budgets (Part 2) - Gigabyte GA-990FXA-UD7, Gigabyte GA-Z77X-UD5H-WB, Asus Rampage IV Extreme
    Motherboards for All Budgets (Part 1) - Asus M5A97 PRO, Gigabyte GA-Z68AP-D3, Gigabyte GA-990FXA-UD3, Asus P8Z68-V Pro
    OWC Mercury Accelsior 480GB
    Polywell H7700i-400B - Desktop Power In A Tiny Box
    iOS – Tax Time : TapTax, My Tax Return 2012, Income Tax Calculator, ITP
    Eat More Healthy With Calorific
    Fitness Gadget Shootout : Fitness Gadgets (Part 3) - Nike+ Sportwatch GPS, Sony Smartwatch
    Most View
    Plextor M3 Pro 256GB
    Programming .NET Components : Building a Distributed Application (part 4) - Administrative Type Registration, Administrative Configuration Example
    Upgrading to Windows Server 2003 : Planning a Windows NT Domain Upgrade (part 1)
    Getting Familiar with AJAX
    Programming COM+ Security (part 3) - Compiling and Installing the COM+ Application
    Tablet for offices and being on street
    SQL Server 2008 : Monitoring Your Server - Monitoring Your CPU
    JavaScript Patterns : Conventions
    Java Mobile Edition Security : Development and Security Testing (part 1) - Configuring a Development Environment and Installing New Platforms & Emulator
    iPhone 3D Programming : Adding Textures to ModelViewer (part 1) - Enhancing IResourceManager
    Expert computing advice (Part 2)
    iCar - Imagine The Possibilities
    Host-Based Security in Windows Vista
    SharePoint 2010 : Outlining the Inherent Threat in SharePoint Web Traffic
    Find it online
    Tasmania - Ideal Destination For Landscape Photographers (Part 2)
    Lenovo IdeaPad Z480 – The Stylish Idealist
    File and Disk Recover And Restore (Part 1) - Binarybiz VirtualLab, Brian Kato Restoration, CGsecurity TestDisk and PhotoRec, Genie9 Timeline Pro 2012, O&O DiskRecovery 7
    Adobe Photoshop CS5 : Working with Automate Commands - Working with Conditional Mode Change, Using the Crop and Straighten Photos Command
    Surviving Changes to the Signature of a Stored Procedure