Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Strategies for Working with Offline Data

Strategies for Working with Offline Data

When your app needs to operate without a network connection, you will need to consider your options for offline or cached data. This session will explore methods for storing data locally and techniques for synchronizing with the backend when your app is online again.

Andrew Duncan

July 18, 2013
Tweet

More Decks by Andrew Duncan

Other Decks in Technology

Transcript

  1. Agenda • Application Cache vs Offline Storage • Data storage

    options • Connecting offline storage to the server • Considerations - Managing Conflicts - Deltas - When to Sync - Sync Frameworks - Security/Privacy - Hybrid App Containers - Performance
  2. Application Cache (AppCache) • Application logic • Browser caches files

    • Specified by developer • Advantages - App works without connectivity - Increased load times - Reduced server load • Cache Manifest • Hybrid App Containers - package resources, e.g. static images, large documents etc...
  3. - Eric Bidelman Offline storage is about capturing specific data

    generated by the user, or resources the user has expressed interest in.
  4. Memory • Reads data from local memory • Contents are

    not retained between sessions • For reading only • Useful to help you translate your data into the correct format in your model.
  5. Memory Proxy Ext.define('MyApp.store.Location',  {        extend:  'Ext.data.Store'  

           autoLoad:  true,        model:  'Location',        proxy:  {                type:  'memory',                reader:  {                        type:  'json'                }        } });
  6. SessionStorage Proxy • Extends WebStorage Proxy • SessionStorage property on

    Window object - accessible from window.SessionStorage • String Key/Value Pairs • Lifetime - data deleted when browsing session ends • Scope - document origin - per-window basis • Size limit - system memory
  7. Session Proxy Ext.define('MyApp.store.Location',  {        extend:  'Ext.data.Store'  

           autoLoad:  true,        model:  'Location',        proxy:  {                type:  'sessionstorage',                id:  'LocationsProxy',                reader:  {                        type:  'json'                }        } });
  8. LocalStorage • LocalStorage property on Window object • Lifetime -

    permanent - deleted by the app - deleted by the user • Scope - document origin - protocol, hostname & port must be the same - browser vendor • Size Limit - 5MB
  9. LocalStorage Proxy Ext.define('MyApp.store.Location',  {        extend:  'Ext.data.Store'  

           autoLoad:  true,        model:  'Location',        proxy:  {                type:  'localstorage',                id:  'LocationsProxy',                reader:  {                        type:  'json'                }        } });
  10. WebSQL Database • Proxy added in Sencha Touch 2.1 •

    Size - defaults to 5MB - developer can request more space from user • Lifetime - permanent - deleted by the app - deleted by the user • Scope - document origin - protocol, hostname & port must be the same - browser vendor • Rollbacks & Data Integrity
  11. SQL Proxy Ext.define('MyApp.store.Location',  {        extend:  'Ext.data.Store'  

           autoLoad:  true,        model:  'Location',        proxy:  {                type:  'sql',                database:  'Assets',                table:  'AssetLocations',                reader:  {                        type:  'json'                }        } });
  12. Multiple Proxies may help • Data can be changed in

    two places - In the backend e.g. by external systems - Requires a connection via a Server Proxy - On the client - Requires a Client Proxy • Benefits are more than just offline working - Perceived performance boost as syncing is local and server syncing can be done in the background - Alleviates slow network connectivity or slow backend • We need a way of knowing/merging the data between the proxies
  13. Overview • Sencha Touch plugin • Extends Ext.data.Store • Two

    proxies - LocalProxy - ServerProxy • Persists a local copy • Keeps a record of added, updated and deleted records • Syncs these changes with your server • Enables you to control when syncing takes place
  14. Ext.define('Example.store.Person',  {        extend:  'Ext.ux.OfflineSyncStore',      

     config:  {                model:  'Example.model.Person',                localProxy:  {                        type:  'localstorage',                        id:  'offline-­‐sync-­‐store'                },                serverProxy:  {                        type:  'ajax',                        api:  {                                read:  '../../server/select.php',                                create:  '../../server/save.php'                        },                        reader:  {                                type:  'json',                                rootProperty:  'rows'                        },                        writer:  {                                allowSingle:  false                        }                }        } });
  15. Conflicts between the Proxies • Dirty and phantom records are

    no longer known • We keep our own record of these - to avoid overwriting data between the proxies and a server load
  16. Conflicts with the Backend • Timestamp all data • Keep

    a version number • Possible Solutions - Last write wins - trust the local time to be truthful - Privilege • Application dependent, no right or wrong answer
  17. When Should I Sync? • Try all the time •

    Ajax request will fail if no connectivity. • Stack up failures and resend • Time driven • Event/Action driven • Monitoring Connectivity • Phonegap • navigator.connection.type • Sencha Touch • Ext.device.Connection • HTML5 • navigator.onLine • definition of ‘online’ varies • local network or internet • Solution is detect a heartbeat Poor Connectivity As soon as connectivity is regained? Good Connectivity All the time?
  18. Data Loss During the Sync • Problem - New data

    can be lost if the store is currently ‘syncing’ • Cause - Slower & older devices - large datasets • Possible Solution - Pause user interaction while sync is in progress. - Framework Override to stop the date clear happening so early.
  19. Deltas • Improves performance / Reduces Bandwidth • Require your

    app to have knowledge of when its data was last updated • Server only sends newly updated between the current time and the last sync • Data is merged with store • Sencha Touch handles this well for us already
  20. Is the hardwork done for us? • RhoConnect • WebSqlSync

    - https://github.com/orbitaloop/WebSqlSync/ • PouchDB
  21. HTML5 Storage Security • Do not store session identifiers -

    Cookies can use the httpOnly flag - SessionStorage might be ok for • Encryption is an option - Stanford Javascript Crypto Library - http://crypto.stanford.edu/sjcl/ - AES - Override the proxy
  22. Hybrid App Containers • RhoMobile - Rhom Local database -

    SQLite - Database encryption • PhoneGap - Use SQLLite Plugin - SQLCipher - Open Source - 256-bit encryption - http://brodyspark.blogspot.co.uk/ - Don’t store the key - derive from users password • Sencha Space
  23. Remote Wiping Data • Use a mobile device management suite

    - AirWatch - Soti MobiControl • Sencha Space
  24. Take the Survey! • Session Survey - Available on the

    SenchaCon mobile app - http://app.senchacon.com • Be Social! - @SenchaCon - #SenchaCon - @andrewmduncan