SlideShare a Scribd company logo
1 of 43
Download to read offline
Taking
web apps
offline

                        pedro@morais.it
                          @pedromorais
GDG Portugal DevFest   morais on app.net
     March ’13
Offline webapps - why?

 no network connection required
 faster startup
 keep data local
The Road to Offline


    user data

     assets
1. user data
localStorage
    *and sessionStorage
localstorage

              Simple API


window.localStorage[‘hello’] = ‘world’;
localStorage
       Can store a JSON string


window.localStorage[‘helloJSON’] =
 JSON.stringify({‘key1’: ‘world’,
       ‘key2’: ‘Lisbon’});
92.25%   http://caniuse.com/indexeddb
localStorage limitations
           Storage Limits


            Spec - 5 Mb
        Firefox - can adjusted
  Chrome - 2600k chars   (5 mb in UTF-16)

          IE - 5000k chars
localStorage limitations
              Sync API


   window.localStorage[‘sloooow’] =
     ‘imagine a 1 MB string here’;
sql storage
sql storage
     work stopped November ’10


 sqlite was used in all implementations
            (webkit, opera)


mozilla & microsoft: “not gonna happen”
48.32%   http://caniuse.com/sql-storage
sql storage

http://nparashuram.com/IndexedDBShim/


    indexed db polyfill over websql
indexed db
indexed db
                     Async API


var request = indexedDB.doStuff();
request.onerror = function(event) {
 ...
};
request.onsuccess = function(event) {
 ...
};
indexed db
               Opening a database


var request = indexedDB.open("MyTestDatabase");
request.onerror = ...
var db;
request.onsuccess = function(event) {
 db = request.result;
};
creating the schema

var request = indexedDB.open("MyTestDatabase", 5);
...
request.onupgradeneeded = function(event) {
 var db = event.target.result;
 ...
};
creating the schema
# student: cardNumber, name, email, ...
request.onupgradeneeded = function(event) {
 var db = event.target.result;
 var studentsStore = db.createObjectStore("students",
                               { keyPath: "cardNumber" });
     studentsStore.createIndex("nameIndex", "name",
                              { unique: false });
     studentsStore.createIndex("emailIndex", "email",
                              { unique: true });
};
adding data
var transaction
     = db.transaction(["students"], "readwrite");


transaction.oncomplete = function(event) {
  alert("All done!");
};


...
// transactions go away when you
// return to the event loop
// without making a request
adding data
...
var objectStore = transaction.objectStore("customers");
aStudent = { ‘studentCard’: ‘44124’,
             ‘name’: ‘Pedro Morais’,
             ‘email’: ‘pedro@morais.it'}


var request = objectStore.add(aStudent);
request.onsuccess = function(event) {
  // event.target.result == aStuddent.studentCard
};
updating data
...
var objectStore = transaction.objectStore("customers");
aStudent = { ‘studentCard’: ‘44124’,
             ‘name’: ‘Pedro Morais with updated name’,
             ‘email’: ‘pedro@morais.it'}


var request = objectStore.put(aStudent);
request.onsuccess = function(event) {
  // event.target.result == aStuddent.studentCard
};
deleting data

...
var objectStore = transaction.objectStore("customers");


var request = objectStore.delete(‘44124’);
request.onsuccess = function(event) {
 // deleted
};
getting data

var transaction = db.transaction(["students"]);
var objectStore = transaction.objectStore("customers");


var request = objectStore.get(‘44124’);
request.onsuccess = function(event) {
 console.log(“Name is “, request.result.name);
};
using a cursor
....


var request = objectStore.openCursor();
request.onsuccess = function(event) {
     var c = event.target.result;
  if (c) {
    console.log
          ("Student " + c + " is named " + c.value.name);
    cursor.continue();
  } else {
    console.log("Done!");
  }
};
using an index

...
var index = objectStore.index("name");
index.get("Pedro Morais").onsuccess = function(event) {
  console.log("Email=" + event.target.result.email);
};


// if name is not unique
// you get the first entry that matches
using an index + cursor
...
var index = objectStore.index("name");
var request
     = index.openCursor(IDBKeyRange.only("Pedro Morais"));
request.onsuccess = function(event) {
  var c = event.target.result;
  if (c) {
    // c.key is a name, like "Pedro Morais",
       // c.value is the whole object.
    console.log("Name: " + cursor.key +
                   “Email: " + cursor.value.email);
    cursor.continue();
  }
};
cursor key ranges

IDBKeyRange.only("Pedro Morais")
IDBKeyRange.lowerBound("Pedro")
IDBKeyRange.lowerBound("Pedro", true) // don’t inc Pedro
IDBKeyRange.upperBound("Pedro", true) // don’t inc Pedro


IDBKeyRange.bound("Pedro", "Vanda", false, true);
// include Pedro, don’t include Vanda
46.93%   http://caniuse.com/indexeddb
2. assets
offline web apps
67.43%   http://caniuse.com/offline-apps
offline web apps
<!DOCTYPE html>
<html manifest=”cache.appcache”>
...


  cache.appcache must be served as
       text/cache-manifest
cache manifest
CACHE MANIFEST
# this is a comment

css/styles.css
js/scripts.js
images/logo.png

NETWORK:
*
cache with fallback
CACHE MANIFEST
# this is a comment

css/styles.css
js/scripts.js
images/logo.png

FALLBACK:
/ /offline.html

NETWORK:
*
network access
                    not using appcache

• user navigates to http://test.com/app.html
• browser check if file “app.html” is in cache
• browser check if it has not expired
• browser checks validity of file using etags (optional)
• browser renders the cached or downloaded app.html
network access
                       using appcache

• user navigates to http://test.com/app.html
• browser renders app.html from appcache
• in the background:
  • browser checks if manifest has changed
  • if it has, browser downloads all files in the manifest
    (expires, etags still apply)

  • user only gets new version of app.html the next time!
cache manifest versions
 CACHE MANIFEST
 # version 50

 css/styles.css
 js/scripts.js
 images/logo.png

 NETWORK:
 *
cache manifest versions
 CACHE MANIFEST

 css/styles.css?b3c4de
 js/scripts.js?adf341
 images/logo.png?ef3451

 NETWORK:
 *


                          + far future expires
cache manifest versions
 CACHE MANIFEST

 b3c4de/css/styles.css
 adf341/js/scripts.js
 ef3451/images/logo.png

 NETWORK:
 *


                          + far future expires
conclusion
Available today

   localStorage
 Indexed DB (+ polyfill)
    AppCache

Take your web apps offline
Thanks!



                        pedro@morais.it
                          @pedromorais
GDG Portugal DevFest   morais on app.net
     March ’13

More Related Content

What's hot

Authentication
AuthenticationAuthentication
Authentication
soon
 
Google
GoogleGoogle
Google
soon
 
Simplify AJAX using jQuery
Simplify AJAX using jQuerySimplify AJAX using jQuery
Simplify AJAX using jQuery
Siva Arunachalam
 
SH 1 - SES 8 - Stitch_Overview_TLV.pptx
SH 1 - SES 8 - Stitch_Overview_TLV.pptxSH 1 - SES 8 - Stitch_Overview_TLV.pptx
SH 1 - SES 8 - Stitch_Overview_TLV.pptx
MongoDB
 
Deploying
DeployingDeploying
Deploying
soon
 

What's hot (17)

Authentication
AuthenticationAuthentication
Authentication
 
Google
GoogleGoogle
Google
 
handout-05b
handout-05bhandout-05b
handout-05b
 
Html5 For Jjugccc2009fall
Html5 For Jjugccc2009fallHtml5 For Jjugccc2009fall
Html5 For Jjugccc2009fall
 
Getting classy with ES6
Getting classy with ES6Getting classy with ES6
Getting classy with ES6
 
AngulrJS Overview
AngulrJS OverviewAngulrJS Overview
AngulrJS Overview
 
Simplify AJAX using jQuery
Simplify AJAX using jQuerySimplify AJAX using jQuery
Simplify AJAX using jQuery
 
Introducing jQuery
Introducing jQueryIntroducing jQuery
Introducing jQuery
 
Internet and Web Technology (CLASS-10) [Node.js] | NIC/NIELIT Web Technology
Internet and Web Technology (CLASS-10) [Node.js] | NIC/NIELIT Web Technology Internet and Web Technology (CLASS-10) [Node.js] | NIC/NIELIT Web Technology
Internet and Web Technology (CLASS-10) [Node.js] | NIC/NIELIT Web Technology
 
Dynamic Business Processes using Automated Actions
Dynamic Business Processes using Automated ActionsDynamic Business Processes using Automated Actions
Dynamic Business Processes using Automated Actions
 
jQuery Best Practice
jQuery Best Practice jQuery Best Practice
jQuery Best Practice
 
Secure WordPress Development Practices
Secure WordPress Development PracticesSecure WordPress Development Practices
Secure WordPress Development Practices
 
SH 1 - SES 8 - Stitch_Overview_TLV.pptx
SH 1 - SES 8 - Stitch_Overview_TLV.pptxSH 1 - SES 8 - Stitch_Overview_TLV.pptx
SH 1 - SES 8 - Stitch_Overview_TLV.pptx
 
State of jQuery and Drupal
State of jQuery and DrupalState of jQuery and Drupal
State of jQuery and Drupal
 
Deploying
DeployingDeploying
Deploying
 
Opensocial Codelab
Opensocial CodelabOpensocial Codelab
Opensocial Codelab
 
jQuery basics
jQuery basicsjQuery basics
jQuery basics
 

Similar to Taking Web Apps Offline

HTML5: huh, what is it good for?
HTML5: huh, what is it good for?HTML5: huh, what is it good for?
HTML5: huh, what is it good for?
Remy Sharp
 
The Magic Revealed: Four Real-World Examples of Using the Client Object Model...
The Magic Revealed: Four Real-World Examples of Using the Client Object Model...The Magic Revealed: Four Real-World Examples of Using the Client Object Model...
The Magic Revealed: Four Real-World Examples of Using the Client Object Model...
SPTechCon
 
BlackBerry DevCon 2011 - PhoneGap and WebWorks
BlackBerry DevCon 2011 - PhoneGap and WebWorksBlackBerry DevCon 2011 - PhoneGap and WebWorks
BlackBerry DevCon 2011 - PhoneGap and WebWorks
mwbrooks
 
jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013
jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013
jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013
Kiril Iliev
 
Firefox OS learnings & visions, WebAPIs - budapest.mobile
Firefox OS learnings & visions, WebAPIs - budapest.mobileFirefox OS learnings & visions, WebAPIs - budapest.mobile
Firefox OS learnings & visions, WebAPIs - budapest.mobile
Robert Nyman
 
Javascript MVC & Backbone Tips & Tricks
Javascript MVC & Backbone Tips & TricksJavascript MVC & Backbone Tips & Tricks
Javascript MVC & Backbone Tips & Tricks
Hjörtur Hilmarsson
 
JavaScript para Graficos y Visualizacion de Datos
JavaScript para Graficos y Visualizacion de DatosJavaScript para Graficos y Visualizacion de Datos
JavaScript para Graficos y Visualizacion de Datos
philogb
 
JavaScript para Graficos y Visualizacion de Datos - BogotaJS
JavaScript para Graficos y Visualizacion de Datos - BogotaJSJavaScript para Graficos y Visualizacion de Datos - BogotaJS
JavaScript para Graficos y Visualizacion de Datos - BogotaJS
philogb
 
JavaScript APIs - The Web is the Platform
JavaScript APIs - The Web is the PlatformJavaScript APIs - The Web is the Platform
JavaScript APIs - The Web is the Platform
Robert Nyman
 

Similar to Taking Web Apps Offline (20)

IndexedDB and Push Notifications in Progressive Web Apps
IndexedDB and Push Notifications in Progressive Web AppsIndexedDB and Push Notifications in Progressive Web Apps
IndexedDB and Push Notifications in Progressive Web Apps
 
Parse London Meetup - Cloud Code Tips & Tricks
Parse London Meetup - Cloud Code Tips & TricksParse London Meetup - Cloud Code Tips & Tricks
Parse London Meetup - Cloud Code Tips & Tricks
 
HTML5: huh, what is it good for?
HTML5: huh, what is it good for?HTML5: huh, what is it good for?
HTML5: huh, what is it good for?
 
The Magic Revealed: Four Real-World Examples of Using the Client Object Model...
The Magic Revealed: Four Real-World Examples of Using the Client Object Model...The Magic Revealed: Four Real-World Examples of Using the Client Object Model...
The Magic Revealed: Four Real-World Examples of Using the Client Object Model...
 
Firefox OS, une plateforme à découvrir - IO Saglac - 2014-09-09
Firefox OS, une plateforme à découvrir - IO Saglac - 2014-09-09Firefox OS, une plateforme à découvrir - IO Saglac - 2014-09-09
Firefox OS, une plateforme à découvrir - IO Saglac - 2014-09-09
 
BlackBerry DevCon 2011 - PhoneGap and WebWorks
BlackBerry DevCon 2011 - PhoneGap and WebWorksBlackBerry DevCon 2011 - PhoneGap and WebWorks
BlackBerry DevCon 2011 - PhoneGap and WebWorks
 
jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013
jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013
jsSaturday - PhoneGap and jQuery Mobile for SharePoint 2013
 
Firefox OS learnings & visions, WebAPIs - budapest.mobile
Firefox OS learnings & visions, WebAPIs - budapest.mobileFirefox OS learnings & visions, WebAPIs - budapest.mobile
Firefox OS learnings & visions, WebAPIs - budapest.mobile
 
Javascript MVC & Backbone Tips & Tricks
Javascript MVC & Backbone Tips & TricksJavascript MVC & Backbone Tips & Tricks
Javascript MVC & Backbone Tips & Tricks
 
JavaScript para Graficos y Visualizacion de Datos
JavaScript para Graficos y Visualizacion de DatosJavaScript para Graficos y Visualizacion de Datos
JavaScript para Graficos y Visualizacion de Datos
 
The Hitchhikers Guide To Html5 Offline Strategies (+firefoxOS)
The Hitchhikers Guide To Html5 Offline Strategies (+firefoxOS)The Hitchhikers Guide To Html5 Offline Strategies (+firefoxOS)
The Hitchhikers Guide To Html5 Offline Strategies (+firefoxOS)
 
HTML5 tutorial: canvas, offfline & sockets
HTML5 tutorial: canvas, offfline & socketsHTML5 tutorial: canvas, offfline & sockets
HTML5 tutorial: canvas, offfline & sockets
 
JavaScript para Graficos y Visualizacion de Datos - BogotaJS
JavaScript para Graficos y Visualizacion de Datos - BogotaJSJavaScript para Graficos y Visualizacion de Datos - BogotaJS
JavaScript para Graficos y Visualizacion de Datos - BogotaJS
 
Future of Web Apps: Google Gears
Future of Web Apps: Google GearsFuture of Web Apps: Google Gears
Future of Web Apps: Google Gears
 
Sebastian Schmidt, Rachel Myers - How To Go Serverless And Not Violate The GD...
Sebastian Schmidt, Rachel Myers - How To Go Serverless And Not Violate The GD...Sebastian Schmidt, Rachel Myers - How To Go Serverless And Not Violate The GD...
Sebastian Schmidt, Rachel Myers - How To Go Serverless And Not Violate The GD...
 
HTML for the Mobile Web, Firefox OS - All Things Open - 2014-10-22
HTML for the Mobile Web, Firefox OS - All Things Open - 2014-10-22HTML for the Mobile Web, Firefox OS - All Things Open - 2014-10-22
HTML for the Mobile Web, Firefox OS - All Things Open - 2014-10-22
 
Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017Full stack development with node and NoSQL - All Things Open - October 2017
Full stack development with node and NoSQL - All Things Open - October 2017
 
Full Stack Development with Node.js and NoSQL
Full Stack Development with Node.js and NoSQLFull Stack Development with Node.js and NoSQL
Full Stack Development with Node.js and NoSQL
 
HTML, not just for desktops: Firefox OS - Congreso Universitario Móvil - 201...
HTML, not just for desktops: Firefox OS - Congreso Universitario Móvil - 201...HTML, not just for desktops: Firefox OS - Congreso Universitario Móvil - 201...
HTML, not just for desktops: Firefox OS - Congreso Universitario Móvil - 201...
 
JavaScript APIs - The Web is the Platform
JavaScript APIs - The Web is the PlatformJavaScript APIs - The Web is the Platform
JavaScript APIs - The Web is the Platform
 

Recently uploaded

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Recently uploaded (20)

Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 

Taking Web Apps Offline

  • 1. Taking web apps offline pedro@morais.it @pedromorais GDG Portugal DevFest morais on app.net March ’13
  • 2. Offline webapps - why? no network connection required faster startup keep data local
  • 3. The Road to Offline user data assets
  • 5. localStorage *and sessionStorage
  • 6. localstorage Simple API window.localStorage[‘hello’] = ‘world’;
  • 7. localStorage Can store a JSON string window.localStorage[‘helloJSON’] = JSON.stringify({‘key1’: ‘world’, ‘key2’: ‘Lisbon’});
  • 8. 92.25% http://caniuse.com/indexeddb
  • 9. localStorage limitations Storage Limits Spec - 5 Mb Firefox - can adjusted Chrome - 2600k chars (5 mb in UTF-16) IE - 5000k chars
  • 10. localStorage limitations Sync API window.localStorage[‘sloooow’] = ‘imagine a 1 MB string here’;
  • 12. sql storage work stopped November ’10 sqlite was used in all implementations (webkit, opera) mozilla & microsoft: “not gonna happen”
  • 13. 48.32% http://caniuse.com/sql-storage
  • 14. sql storage http://nparashuram.com/IndexedDBShim/ indexed db polyfill over websql
  • 16. indexed db Async API var request = indexedDB.doStuff(); request.onerror = function(event) { ... }; request.onsuccess = function(event) { ... };
  • 17. indexed db Opening a database var request = indexedDB.open("MyTestDatabase"); request.onerror = ... var db; request.onsuccess = function(event) { db = request.result; };
  • 18. creating the schema var request = indexedDB.open("MyTestDatabase", 5); ... request.onupgradeneeded = function(event) { var db = event.target.result; ... };
  • 19. creating the schema # student: cardNumber, name, email, ... request.onupgradeneeded = function(event) { var db = event.target.result; var studentsStore = db.createObjectStore("students", { keyPath: "cardNumber" }); studentsStore.createIndex("nameIndex", "name", { unique: false }); studentsStore.createIndex("emailIndex", "email", { unique: true }); };
  • 20. adding data var transaction = db.transaction(["students"], "readwrite"); transaction.oncomplete = function(event) {   alert("All done!"); }; ... // transactions go away when you // return to the event loop // without making a request
  • 21. adding data ... var objectStore = transaction.objectStore("customers"); aStudent = { ‘studentCard’: ‘44124’, ‘name’: ‘Pedro Morais’, ‘email’: ‘pedro@morais.it'} var request = objectStore.add(aStudent); request.onsuccess = function(event) {   // event.target.result == aStuddent.studentCard };
  • 22. updating data ... var objectStore = transaction.objectStore("customers"); aStudent = { ‘studentCard’: ‘44124’, ‘name’: ‘Pedro Morais with updated name’, ‘email’: ‘pedro@morais.it'} var request = objectStore.put(aStudent); request.onsuccess = function(event) {   // event.target.result == aStuddent.studentCard };
  • 23. deleting data ... var objectStore = transaction.objectStore("customers"); var request = objectStore.delete(‘44124’); request.onsuccess = function(event) { // deleted };
  • 24. getting data var transaction = db.transaction(["students"]); var objectStore = transaction.objectStore("customers"); var request = objectStore.get(‘44124’); request.onsuccess = function(event) { console.log(“Name is “, request.result.name); };
  • 25. using a cursor .... var request = objectStore.openCursor(); request.onsuccess = function(event) { var c = event.target.result;   if (c) {     console.log ("Student " + c + " is named " + c.value.name);     cursor.continue();   } else {     console.log("Done!");   } };
  • 26. using an index ... var index = objectStore.index("name"); index.get("Pedro Morais").onsuccess = function(event) {   console.log("Email=" + event.target.result.email); }; // if name is not unique // you get the first entry that matches
  • 27. using an index + cursor ... var index = objectStore.index("name"); var request = index.openCursor(IDBKeyRange.only("Pedro Morais")); request.onsuccess = function(event) {   var c = event.target.result;   if (c) {     // c.key is a name, like "Pedro Morais", // c.value is the whole object.     console.log("Name: " + cursor.key + “Email: " + cursor.value.email);     cursor.continue();   } };
  • 28. cursor key ranges IDBKeyRange.only("Pedro Morais") IDBKeyRange.lowerBound("Pedro") IDBKeyRange.lowerBound("Pedro", true) // don’t inc Pedro IDBKeyRange.upperBound("Pedro", true) // don’t inc Pedro IDBKeyRange.bound("Pedro", "Vanda", false, true); // include Pedro, don’t include Vanda
  • 29. 46.93% http://caniuse.com/indexeddb
  • 32. 67.43% http://caniuse.com/offline-apps
  • 33. offline web apps <!DOCTYPE html> <html manifest=”cache.appcache”> ... cache.appcache must be served as text/cache-manifest
  • 34. cache manifest CACHE MANIFEST # this is a comment css/styles.css js/scripts.js images/logo.png NETWORK: *
  • 35. cache with fallback CACHE MANIFEST # this is a comment css/styles.css js/scripts.js images/logo.png FALLBACK: / /offline.html NETWORK: *
  • 36. network access not using appcache • user navigates to http://test.com/app.html • browser check if file “app.html” is in cache • browser check if it has not expired • browser checks validity of file using etags (optional) • browser renders the cached or downloaded app.html
  • 37. network access using appcache • user navigates to http://test.com/app.html • browser renders app.html from appcache • in the background: • browser checks if manifest has changed • if it has, browser downloads all files in the manifest (expires, etags still apply) • user only gets new version of app.html the next time!
  • 38. cache manifest versions CACHE MANIFEST # version 50 css/styles.css js/scripts.js images/logo.png NETWORK: *
  • 39. cache manifest versions CACHE MANIFEST css/styles.css?b3c4de js/scripts.js?adf341 images/logo.png?ef3451 NETWORK: * + far future expires
  • 40. cache manifest versions CACHE MANIFEST b3c4de/css/styles.css adf341/js/scripts.js ef3451/images/logo.png NETWORK: * + far future expires
  • 42. Available today localStorage Indexed DB (+ polyfill) AppCache Take your web apps offline
  • 43. Thanks! pedro@morais.it @pedromorais GDG Portugal DevFest morais on app.net March ’13