Purple App Experience
Offline behavior
12 min
purple native apps still work when your device isn't connected to the internet however, there are some limits to what you can do without an internet connection this article explains offline behavior and how you can define an offline view to let your users know that they are currently not online while using your app offline behavior in purple apps purple native apps still work even if your users' devices aren't connected to the internet however, there are some limits on what you can do without internet connectivity here are the basics first time usage of the app the first time using the app, the user needs to be connected to the internet; on subsequent starts, the app can be started without network connectivity offline available data data in the dynamic resources is generally available offline, e g , view configs data from the content cloud that is fetched using, e g , data sources is generally only available online this includes but is not limited to contents, publications, collections, taxonomies, and menus data that is loaded while the device is online may be cached for a moment and therefore available offline but is subject to automatic clearing by the system or other factors, e g , signing in or out the only exception is the content data source using the local config this will be explained in the offline behavior /#downloaded content view section sign in/out when signing in or signing out, the cache is cleared, and content will disappear or queries will not be resolved this happens because some options within the app change depending on the login status when trying to sign in or sign out in offline mode, it's likely that the user won't be able to see views while staying offline downloaded content define offline views to ensure consistent usability while being offline, we recommend creating a view that displays all content that is completely or depending on your desired behavior partially available for offline usage to ensure the app gracefully starts in offline mode, ensure there is no data from online sources needed upon startup implement proper fallbacks here; otherwise, you might end up in an undefined state to ensure your users can easily find this view, you can trigger a message if the device is offline and link directly to the aforementioned view downloaded content view this view shows content you've explicitly saved downloaded content behaviour we do not explicitly download thumbnails , so they will only appear if the user has had a look at the downloads page before going offline and is still cached by the os contents that were not fully downloaded yet can be opened but will only show the parts that were downloaded until this point here's how to do that in experience builder > views json, you can create a view to display downloaded content, including partially downloaded elements views json in experience builder note that the actual value of the emptymessage is controlled via messages json for further details on that, see messages json static texts docid 2l6zp7jyafzv xnfoy8u0 instead of using the boolean true for local, it is also possible to provide a string, which uses a $function in that case, we provide $context local and $context states, which can be used as parameters for filtering the local contents for further criteria $context local provides an array of locally available contents, which were manually downloaded these contents may still be downloading $context states is a map from content id to content states, which can be used to filter for contents of certain states, e g , only showing fully downloaded contents the following example shows a filter function that returns only fully downloaded contents window $functions = { filterlocalcontents (local, states) => { if (!local || !states) { return \[]; } return local filter(content => { return states\[content id] installstate === 'complete'; }) } } using the above example, the string value for local on the data source should look like this $functions filterlocalcontents($context local, $context states) due to some limitations, this $function may be called without local and states available in that case, please always return an empty array when using local, either as a boolean or string, any filters applied to the data source will not have any effect, as the source for the local contents is the device and not the backend for further filtering, please use the $function approach mentioned above now that you can list locally available contents, you need to configure a way to open such contents offline if the app only serves content of type issue , then adding an opencontentaction to either tapcover or tapcontent is sufficient, and the setup is done these issues will then be opened by the native presenter, and users can view them offline, assuming they were fully downloaded if the app also serves contents of type bundle , then a few additional configuration steps are required define a navigation action to an offline content view adjust the url resolver to fetch the local content and provide it as context build the offline content view for issues , use standard open content action for posts and bundles , define a navigation action that points to a view that works offline this can be achieved by using a conditional on, e g , tapcover or tapcontent if the contenttype of the content is issue , the opencontentaction should be used; otherwise, a navigateaction , which in the above example links to the path offline/$context content id depending on your needs, the path may be different, but the important piece here is that the content id has to be used, not a slug or any other information, since the url resolver can only access offline content by its id views json in experience builder now in the url resolver, configure a corresponding entry for the offline path, which then loads the content using the dataresolver's findcontentbyid function and then provides this content as context to a content view additionally, this resolver entry has to set skipresolving to true to disable automatic path segment resolution, since this is neither available offline nor needed for our case the findcontentbyid function from the dataresolver is the only function that can serve data offline it will always attempt to restore the content from the cache before attempting a network request this also means that in online scenarios, this function might return stale data this function also takes optional fetchoptions, which may be needed for, e g , displaying a bundle's toc the following minimal example matches the above configuration using a path offline followed by the content id { pathpattern '/offline/\ contentid', skipresolving true, viewresolver async ({dataresolver, match}) => { const content = await dataresolver findcontentbyid(match params contentid) return { viewname "content", viewcontext { content } } } } finally, configure the corresponding content view in a minimal example it is sufficient to just show a content body component, which takes the content from the context depending on your needs, this view can be extended, e g , for showing the toc or swiping between articles keep in mind to only reference the content provided from the context, or if other data is needed, to provide it from the url resolver offline notification and link you can create a message that will be triggered if the device is offline the following section is outdated the same outcome may be achieved utilizing presets please refer to split views docid\ kxmx0xdffeldjq7z4lqlx for further information to ensure maintainability, this should be done in two steps a) creation of a view with the desired message and behavior not depicted, but possible, is to add further tracking parameters to that view as well (see configure views for tracking docid fg4ut3gcm6zfwalv ocb for details) you are free to add css accordingly to style that part to your need b) inserting that view into any other view where you want to display the message with this approach, you can make significant changes to the message without manually altering many views you also get the freedom to integrate other elements that you trigger on specific conditions