HTML5 and OfflineDavid OrchardMobile Architect
OutlineEasy stuffWeb StorageApp CacheWeb SQLHard stuffNamingCache invalidationWritingOh, and security
HTML5
Web StorageAka HTML5 StorageSessionStorageScoped to sessionNo sharing across windowsLocalStoragePersistentShared across windowsSize: 5M, 10M, expandable
Web storage API	setItem(key, value)sessionStorage.setItem(key, value)sessionStorage.key=valuesessionStorage[‘key’]=valuegetItem(key)removeItem(key)lengthkey(index)clear
WebStorage data typesStringThat’s it.Use JSON to serialize/deserialize structuresJson.org/json2.jsCareful of serializing too much
Web storage tips/referencestry {    return 'localStorage' in window && window['localStorage'] !== null;} catch (e) {    return false; }}Modernizr.sessionstorageModernizr.localstoragehttp://diveintohtml5.org/storage.html
HTML5 Cache ManifestCentral resource for html5 caching<!DOCTYPE HTML><html manifest=“/appcache.manifest”><body></body></html>Every page in your app must refer to the manifest
Serving Cache ManifestMust be content-type text/cache-manifestDocument name must end in .manifestWatch out for HTTP caching the manifestMake sure cache file gets refreshed when you refreshCan tell if clearing the cache worksOr just the checking event fired (events coming up)Configure server to tell browser to not cache manifest
Cache Manifest	CACHE MANIFEST#version 13#equivalent to CACHE: section/index.html/wickedjslib.js/awesomestyle.cssNETWORK:*FALLBACK:/ /fallback.html
Browser behaviorUser may be offered option of saving data to app cacheSet size of App CacheClear the app cache by clearing cacheCan also view app caches:chrome://appcache-internals/Private Browsing disables app cacheMobile 
Cache Manifest loading processHTTP load .manifest filePreviously mentioned HTTP Caching issueDetermine if new version of cache manifestUses HTTP last-modifiedChange manifest file every time file changesAutomate!Download
Cache eventscheckingdownloadingprogress with how many files downloaded, to gonoupdateupdatereadythen do window.applicationCache.swapCache()
Tips/ReferenceModernizr.applicationcacheCharles Proxyhttp://jonathanstark.com/blog/2009/09/27/debugging-html-5-offline-application-cache/Oh, not in iOS for webkithttp://stackoverflow.com/questions/4361948/offline-ios-web-app-loads-my-manifest-but-doesnt-work-offlineWell, maybe from 4.3.2http://diveintohtml5.org/offline.html
Web SQLOpenDatabase(name, version, descr, size)var db = openDatabase(‘mdb’,’1.0’,’hello world db’, 1*1024*1024)Version # is magicdb.transaction(function(tx){tx.executeSQL(‘CREATE TABLE test(id,text)’);tx.executeSQL(‘INSERT INTO test VALUES(1,”hello”)’);tx.executeSQL(‘SELECT * FROM foo’, [], callback);});function(tx, results){// results.rows.items(i).text}
TipsModernizr.websqldatabaseAsync FTWReset db method on deviceDOM ERROR 11 means db broken
Other OfflineDevice specific librariesCalendarContactsW3C Device APIs WGSure, let’s call it HTML5
ProductsSencha’s Ext, iojQuery offlineGWTMagicPref
Hard stuffNamingCache invalidationthx Phil Karlton
NamingWeb arch anyone?http://www.w3.org/TR/webarch/Also Roy’s thesis
Representationshttp://lists.w3.org/Archives/Public/www-tag/2002Oct/0079.htmlSo, then, how do you bend a spoon? Simple. Drop a graphics processor onto the interface such that the representations are morphed. The spoon appears to bend because you have no way of distinguishing one implementation from another, unless you happen to be the One in control of the implementation.  And, because of that, bending the representations is sufficient for other observers to think that you have actually bended the spoon.
Cache Invalidation aka bending the spoonHow about client-side write?Phases0. No client side write1. Write to server, refresh cache2. Write to cache, then serverSync everythingDeltasChoices depend upon latencyWhat if network breaks or device shuts off partway?When to update UI?
DeltasClient actions stored as deltas in command queueServer responds with absolute or delta?Combine with Server updatesIf server responds with invalid state or denies commandhave to drain the queue and stopHold off on UI updates if many pending requestshttp://googlecode.blogspot.com/2009/06/gmail-for-mobile-html5-series-cache.html
Offline detectionnavigator.onLine is usually just wrongMaybe message failsOr even worse, slow connection with partial messageNeed a ping serviceTip: provide a config that you can turn on/off during app
The joy that is reliable messagingAsynchronous messagingNever do synchronous for writesNo response could mean:Outbound message lostFailure on serverWhere on server processing?Inbound message lostRetry synchronous could mean dup messagesDuplicate detectionTry for idempotency
But wait, there’s more: multi-party rm scenarioUser buys in-app purchaseApple send back confirmation with receiptVerify receipt with your serverServer talks to appleRespond to device
SecuritynoneGood luck doing crypto in jsOh, right, export laws.That’s why apple asks you every timePIN/Password to access crypto item. Where to store the key?Need native store for securityEven better, use native code for crypto
OutlineEasy stuffWeb StorageApp CacheWeb SQLHard stuffNamingCache invalidationWritingOh, and security

Dave Orchard - Offline Web Apps with HTML5

  • 1.
    HTML5 and OfflineDavidOrchardMobile Architect
  • 2.
    OutlineEasy stuffWeb StorageAppCacheWeb SQLHard stuffNamingCache invalidationWritingOh, and security
  • 3.
  • 4.
    Web StorageAka HTML5StorageSessionStorageScoped to sessionNo sharing across windowsLocalStoragePersistentShared across windowsSize: 5M, 10M, expandable
  • 5.
    Web storage API setItem(key,value)sessionStorage.setItem(key, value)sessionStorage.key=valuesessionStorage[‘key’]=valuegetItem(key)removeItem(key)lengthkey(index)clear
  • 6.
    WebStorage data typesStringThat’sit.Use JSON to serialize/deserialize structuresJson.org/json2.jsCareful of serializing too much
  • 7.
    Web storage tips/referencestry{ return 'localStorage' in window && window['localStorage'] !== null;} catch (e) { return false; }}Modernizr.sessionstorageModernizr.localstoragehttp://diveintohtml5.org/storage.html
  • 8.
    HTML5 Cache ManifestCentralresource for html5 caching<!DOCTYPE HTML><html manifest=“/appcache.manifest”><body></body></html>Every page in your app must refer to the manifest
  • 9.
    Serving Cache ManifestMustbe content-type text/cache-manifestDocument name must end in .manifestWatch out for HTTP caching the manifestMake sure cache file gets refreshed when you refreshCan tell if clearing the cache worksOr just the checking event fired (events coming up)Configure server to tell browser to not cache manifest
  • 10.
    Cache Manifest CACHE MANIFEST#version13#equivalent to CACHE: section/index.html/wickedjslib.js/awesomestyle.cssNETWORK:*FALLBACK:/ /fallback.html
  • 11.
    Browser behaviorUser maybe offered option of saving data to app cacheSet size of App CacheClear the app cache by clearing cacheCan also view app caches:chrome://appcache-internals/Private Browsing disables app cacheMobile 
  • 12.
    Cache Manifest loadingprocessHTTP load .manifest filePreviously mentioned HTTP Caching issueDetermine if new version of cache manifestUses HTTP last-modifiedChange manifest file every time file changesAutomate!Download
  • 13.
    Cache eventscheckingdownloadingprogress withhow many files downloaded, to gonoupdateupdatereadythen do window.applicationCache.swapCache()
  • 14.
    Tips/ReferenceModernizr.applicationcacheCharles Proxyhttp://jonathanstark.com/blog/2009/09/27/debugging-html-5-offline-application-cache/Oh, notin iOS for webkithttp://stackoverflow.com/questions/4361948/offline-ios-web-app-loads-my-manifest-but-doesnt-work-offlineWell, maybe from 4.3.2http://diveintohtml5.org/offline.html
  • 15.
    Web SQLOpenDatabase(name, version,descr, size)var db = openDatabase(‘mdb’,’1.0’,’hello world db’, 1*1024*1024)Version # is magicdb.transaction(function(tx){tx.executeSQL(‘CREATE TABLE test(id,text)’);tx.executeSQL(‘INSERT INTO test VALUES(1,”hello”)’);tx.executeSQL(‘SELECT * FROM foo’, [], callback);});function(tx, results){// results.rows.items(i).text}
  • 16.
    TipsModernizr.websqldatabaseAsync FTWReset dbmethod on deviceDOM ERROR 11 means db broken
  • 17.
    Other OfflineDevice specificlibrariesCalendarContactsW3C Device APIs WGSure, let’s call it HTML5
  • 18.
  • 19.
  • 20.
  • 22.
    Representationshttp://lists.w3.org/Archives/Public/www-tag/2002Oct/0079.htmlSo, then, howdo you bend a spoon? Simple. Drop a graphics processor onto the interface such that the representations are morphed. The spoon appears to bend because you have no way of distinguishing one implementation from another, unless you happen to be the One in control of the implementation. And, because of that, bending the representations is sufficient for other observers to think that you have actually bended the spoon.
  • 23.
    Cache Invalidation akabending the spoonHow about client-side write?Phases0. No client side write1. Write to server, refresh cache2. Write to cache, then serverSync everythingDeltasChoices depend upon latencyWhat if network breaks or device shuts off partway?When to update UI?
  • 24.
    DeltasClient actions storedas deltas in command queueServer responds with absolute or delta?Combine with Server updatesIf server responds with invalid state or denies commandhave to drain the queue and stopHold off on UI updates if many pending requestshttp://googlecode.blogspot.com/2009/06/gmail-for-mobile-html5-series-cache.html
  • 25.
    Offline detectionnavigator.onLine isusually just wrongMaybe message failsOr even worse, slow connection with partial messageNeed a ping serviceTip: provide a config that you can turn on/off during app
  • 26.
    The joy thatis reliable messagingAsynchronous messagingNever do synchronous for writesNo response could mean:Outbound message lostFailure on serverWhere on server processing?Inbound message lostRetry synchronous could mean dup messagesDuplicate detectionTry for idempotency
  • 27.
    But wait, there’smore: multi-party rm scenarioUser buys in-app purchaseApple send back confirmation with receiptVerify receipt with your serverServer talks to appleRespond to device
  • 28.
    SecuritynoneGood luck doingcrypto in jsOh, right, export laws.That’s why apple asks you every timePIN/Password to access crypto item. Where to store the key?Need native store for securityEven better, use native code for crypto
  • 29.
    OutlineEasy stuffWeb StorageAppCacheWeb SQLHard stuffNamingCache invalidationWritingOh, and security