AG • Focus on – Mobile & web-based application architectures – Interoperability, cross-device – Pragmatic end-to-end solutions • Microsoft MVP for ASP.NET (Architecture) ASP.NET Web API / vNext Advisory Board Member ASPInsider, AzureInsider • Google GDE for AngularJS • http://blogs.thinktecture.com/cweyer [email protected] @christianweyer 2
not enough • Few web sites are designed to work offline • Few web apps are designed to work offline • Few mobile apps are designed to work offline • Offline-First == User-First 4
Aggressive caching is a better user experience • Make error messages informative and consistent • Don’t show contradictory information • Don’t let people start something they can’t finish 11
May be unreliable with different results on various platforms • Need to write algorithm to ping well-known endpoint 14 window.addEventListener('load', function() { var status = document.getElementById("status"); function updateOnlineStatus(event) { var condition = navigator.onLine ? "online" : "offline"; status.className = condition; status.innerHTML = condition.toUpperCase(); } window.addEventListener('online', updateOnlineStatus); window.addEventListener('offline', updateOnlineStatus); });
area – Based on root web page • Manifest describes what to cache • API to detect updates and act accordingly • Can be tough to test and debug • Usage information in browsers – chrome://appcache-internals/ in Chrome – help appcache in Firefox Developer Toolbar 17
MANIFEST # v1 2015-09-14 # This is another comment index.html cache.html style.css image1.png # Use from network if available NETWORK: network.html /api # Fallback content FALLBACK: / fallback.html if (window.applicationCache) { window.applicationCache.addEventListener( 'updateready', function() { if (confirm('An update is available. Reload now?')) { window.location.reload(); } }); }
window object • Difference – data stored in localStorage has no expiration time – data stored in sessionStorage gets cleared when the browsing session ends 26
retrieve objects that are indexed with a key – rich query abilities • Changes to the database happen within transactions • Useful for applications that store large amount of data – Also for blobs • API can be challenging to use 30
// Define a schema db.version(1) .stores({ friends: 'name, age' }); // Open the database db.open() .catch(function(error){ alert('Uh oh : ' + error); }); // Find some old friends db.friends .where('age') .above(75) .each(function(friend){ console.log(friend.name); }); // or make a new one db.friends .add({ name: 'Camilla', age: 25 });
different stores • Mozilla‘s localForage is one of them 33 // In localStorage, we would do: localStorage.setItem('key', JSON.stringify('value')); doSomethingElse(); // With localForage, we use callbacks: localforage.setItem('key', 'value', doSomethingElse); // Or we can use Promises localforage.setItem('key', 'value').then(doSomethingElse);<
data needs to be synchronized – From server to device – From device to server • Conflicts will happen, for sure – Conflict resolution is king, but tough – Solutions based on functional requirements & logic • Certain architecture types can help – Like CQRS 34
result of your infrastructure allowing the same dataset to be modified across disconnected systems. The introduction of such conflicts in such a topology is the expected behavior and their programmatic resolution is a core piece of application logic.” 35 https://cloudant.com/blog/introduction-to-document-conflicts-part-two
JSON for documents – JavaScript for MapReduce indexes – Regular HTTP for its API • PouchDB – Open-source JavaScript database – Inspired by CouchDB – Designed to run well within the browser • PouchDB can sync with CouchDB – Consider checking the inner workings of the sync protocol 37
your architecture and your applications for being offline • Think about your users first! • Browsers have simple storages and powerful databases available • Synchronization can be complex and tedious – It all depends on the use cases 38
Internet – https://medium.com/user-experience-design-1/offline-93c2f8396124 • Mobile Apps Offline Support – http://www.infoq.com/articles/mobile-apps-offline-support • Introduction to CQRS – http://www.codeproject.com/Articles/555855/Introduction-to-CQRS • Working with quota on mobile browsers – http://www.html5rocks.com/en/tutorials/offline/quota-research/ • AppCache Nanny – https://github.com/gr2m/appcache-nanny • Gulp-manifest – https://github.com/hillmanov/gulp-manifest 39