So why would you want to make a web app work offline anyway? Mainly because there are lots of situations, where the network connection is not good or temporarily not available: e.g. when travelling, in bigger buildings (like warehouses), etc. Most Fiori apps are basically a remote control for some SAP backend functionality and loosing the connection in midstream sure can be quite frustrating for the user. So since most logic still happens on server side, we are actually talking about being part-time offline. Technically, there are three main problems to solve:
- Required data must be accessible offline (e.g. the current worklist).
- Changes in the data and action calls, that would normally be sent to the server right away, must be processed on the client and sent to the server later, once the connection is established again.
So, in a nutshell, we need to keep a copy the app structure and a subset of the data on the client and sync them with the server whenever possible. This is far from trivial as web browsers normally just render whatever a server gives them and do not store anything for longer use. Luckily, there are multiple ways to overcome these difficulties.
The following feature matrix shows all the possibilities in direct comparison. Scroll down or click on the table heading for a brief introduction to the selected approach.
|Feature||SAP offline oData + Cordova||Neptune UXP||Progressive Web Apps||AppCache|
|Installation on device required||Yes||No||No||No|
|App can be started offline||Yes||No||Yes||Yes|
|Data subset can be kept offline||Yes (replication)||Yes (replication)||Yes (cache)||Yes (replication)|
|Data can be altered offline and synced later||Yes (sync)||Yes (sync)||Yes (buffer or sync)||Yes (sync)|
|Sync-tools for UI5 available out of the box||Yes||Yes||No||No|
|Prerequisities||SAP Cloud Platform or
SAP Mobile Platform
|Neptune UX Platform||-||-|
|Background-sync||Yes||Yes (if app open in browser)||Yes||No|
|Client-side storage limit *||Device free space (max. 2 TB)||5-50 MB||0,2-1% of device free space||5 MB|
* The storage limit strongly depends on the browser and the operating system. The numbers provided are just typical values to give you an orientation.
** Safari currently (06.2018) only support basice PWA APIs - in particular, the Background Sync API is not yet supported.
SAP provides tools to create hybrid apps within their SAP Cloud Platform or the SAP Mobile Platform. Both use Apache Cordova as container and a set of SAP plugins called "Kapsel framework". Offline support is provided in the form of a middleware called "offline oData". This middleware reads a subset of the server data from a regular oData service and replicates it to connected mobile devices. The mobile app than work only with this data replica, which gets synced back to the middleware by a Kapsel-plugin. The middleware, in turn, will sync further to the original data source. However, the synchronization between app and middleware is not really automatic. SAP provides interfaces, but there is still a lot of coding to be done.
The downside of this approach is being bound to SAP Cloud Platform or SAP Mobile Platform, which can get really expensive depending on your needs. Another problem is the device and version management: in contrast to regular Fiori apps, hybrid ones must get explicitly installed and updated on each device.
It is also important to understand, that such apps will allways work with their data replica (at least for the oData endpoint, that was made offline) - even if currently online. The decision, wether to use offline oData or not, must be made early in the development process as it has significant impact on the code. Additionally, every step in the synchronization may poduce errors or conflicts, which need to be dealt with somehow - see below.
Among other features, there is also a possibility to cache any data for offline use. The idea is similar to SAP's offline oData: you can choose to store a subset of your oData entities in a local database within the client (LocalStorage or WebSQL). This local data is automatically held up to date: All changes are made locally and synced back to the Neptune UX Platform and from there to the SAP backend.
However, Neptune does not provide a way to make the app structure be available offline, so your data will be fine offline, but the app itself will only work as long as you do not close or reload the page in the mobile browser. However, there is a possibility to use Neptune apps within Cordova hybrid apps as discussed above.
Another issue may be the storage limits of the provided client storage options: LocalStorage has a limit of 5 MB in most browsers and WebSQL provides up to 50 MB, but is poorly supported by browsers and even concidered depricated. Again, using Cordova hybrid apps helps overcome these difficulties.
The difference to offline oData and Neptune approaches is here, that the offline data is not neccessarily an exact replica of an oData collection on the server getting synced in the background. The developer is free to choose, wether the app allways works with the offline data or only uses it as a fallback if no connection available. It is even possible to choose different approaches for different requests. This is a lot more flexible, but also requires more carefull application design.
The main advantage of progressive web apps is the simple architecture on client and server side: no containers, no middleware, everything just like in the case of a regular web app. In other words, there is no need to install anything neither on the client nor on the server.
On the downside, there are no ready-made tools for SAP UI5 specifically, so you will need to code all the data synchronization from scratch. Additionally, not all browsers fully support PWA features. You can use my PWA checker to check you target browsers: just open it in the browser of every device you plan to use to see, which features it supports.
Many older UI5 tutorials suggest the use of HTML5 application cache also known as cache manifest. However, this technology is obsolete and is being gradually removed from browsers. In 2016 it had been fully replaced by the Service Worker (see above). In a nutshell, the AppCache allowed to tell the browser to cache certain resources for offline use by linking a special cache manifest in the HTML. That manifest file enumerated all resources to be cached and also those to ignore. This approach did not work well for larger apps with many files as it allowed only basic configuration.
Conflict and error handling
Note, that handling conflicts and server errors is much harder with deffered synchronization, than with immediate server interaction. For example, an object may get altered or even deleted on the server while it was being worked with offlie. There will be no errors when saving that object in offline-mode since the app does not (yet) know, what happened on the server. But the sync will fail in the background while the user is sure to have saved everything correctly. A similar problem arises, when complex plausibility checks are performed on business objects in the server: you don't want to duplicate all that logic in the client.
Neither of the offline approaches discussed here offers a ready-to-use solution for handling background errors. It is up to the developer to create some kind of error log or other visualization and to offer the user ways to deal with conflicts. It is important to keep this in mind, as it may have significant impact on the development costs.