Designing mobile apps for offline mode
For many of us, being disconnected from the web seems like an alien concept. We keep our phones in our pockets all the time and get frustrated when our flight has no Wi-Fi onboard. But for app developers, being disconnected presents additional challenges.
I recently attended DevLink and heard Aaron Powell speak about “airplane mode” and some of the ways to achieve this within mobile web apps. His talk sparked my curiosity and made me wonder how many developers are creating apps with offline mode capabilities as a feature, or “offline first” design principles as some call it.
Whether you are building a commercial app expecting a ton of traffic, or a simpler app consumed by a smaller niche audience, you probably have a minimum viable product (MVP) in mind that you want to deliver to your customers. If you are using a mobile-first approach, this MVP will contain the core lightweight features your customers will need for a pleasing user experience.
That initial user experience usually requires a combination of the following:
- Downloading images and resources
- Handling user input and data sync/upload
- Additional business/app logic
- Validation, versioning, error handling
Nowadays, there is a lot that can be done with HTML5 for mobile web apps to extend the experience offline. Sometime in the past, we were used to retaining a lot of the business logic on the server’s side, thus limiting the client side to basic validation of forms and request handling. Slowly we moved to include more of the app logic on the client side. Preferably, we also minimized the amount of sections inside an app that absolutely required connectivity, in order to improve the user experience. The same is true for native apps; with more apps allowing for offline access, the amount of client side logic has increased too.
When designing offline experiences, some concepts surface that could be applied to both types of apps (native/web).
Many apps require customers to login, authenticate or be connected before accessing certain areas of the app. If possible isolate these sections of the app, so only a minimum set of functionality is withheld from the customers if there is no connectivity. When working with web apps, this isolation can be achieved by utilizing URL paths (/user, /admin, etc.).
This is where the bulk of the offline development efforts go, as we have several items that need to be considered. Storing/updating/retrieving data, is a common task that can be handled in several ways. For web apps, session storage, local storage, IndexDB, etc. can be used as data stores on the client side. For native apps SQLite, NoSQL, or even the local file-system can be used to store data. For both approaches, the data store should be abstracted, so reading or saving new data is decoupled from the connectivity status and user interface.
At the same time, the decision to go route requests online or offline, can be abstracted by mimicking the server side API locally, thus having each call independently handle where to execute the action (depending on success or failure). Unless you are working with proprietary processes, financial transactions, or highly secured systems, consider moving more of the business logic to the app side as part of this local API.
An example of the concept is an app that could have a view where data is shown, in addition to allowing the user to edit this data (e.g. to-do items, notes, etc.). The app will fire the save method and this method will try to connect to the server first; if that fails it will save the data locally. Subsequent successful calls, can update the server with the previous locally cached data, but at no point does the experience become restrictive for the user. A more detailed example of the concept can be found here.
Let’s say you have handled all failed requests and stored all the data locally, client side validation has passed, the customer comes back online, refreshes the page, and gets hit with an error…sigh. What can be done in this case as a multitude of items could be the root cause of this issue (time zones, new versions of the server were deployed, etc.); here is where data classification comes to the rescue. Decide what type of data is critical and what is not. This will help prioritize on the server what needs to be overwritten, merged or ignored. To minimize breaking changes when a new version of the server API is deployed, include the version number in the local and server APIs.
A world of opportunities
Both native and mobile web apps can benefit from an “offline first” approach. I can’t wait to see more apps with this mindset as part of their design. If you want to see an example of a mobile web app with offline capabilities, check the DevLink app; also leave me a comment with some of the apps you love that currently have offline experiences.
For help optimizing your apps, check our AT&T Application Resource Optimizer to diagnose and identify resources to cache and much more.