SaFi Bank Space : Readiness API to Enable Offline Mode

Offline access for mobile app need to be implemented for every journey. Since every journey is different and will have it’s own approach to handle offline behavior, the implementation of each journey needs to be decided by the squads who have more context. Although the approach can be differ from one journey to other journey, a centralized and and flexible mechanism to enable offline access is already implemented and can be used directly to support the journey that needs to be enabled while offline or can be extended for other use case that haven’t known currently. The mechanism is called Readiness.

What is Readiness?

Readiness is a simple wrapper that encapsulates several global app status that can be used to tell whether the app is ready or not. Every journey can refer to Readiness to show the desired behavior based on readiness status that’s needed. Until this page is published, there are 2 status that can be refered from Readiness: isConnected that will tell whether the app is connected to the internet, and isAuthenticated that will tell whether the app can already make authenticated API call to the microservices.

Readiness implementation is a stream of status that can be controlled by the layer that is responsible for a particular status. One example is isConnected status that is dynamically controlled by NetworkInfo everytime the connection status is changed. Since Readiness is stream based, other implementation can subscribe and listen to that status change.

How to Use Readiness?

Since Readiness is quite general and flexible, there are multiple ways to use readiness based on each layers. Below are several implementation that should be enough for most usecase:

Readiness Bloc

ReadinessBloc is an implementation of Readiness based on BLoC mechanism. Since this implemented based on BLoC, it’s usage is best to be used from within a flutter widget, so the state change can be listen by bloc widgets, such as BlocBuilder or BlocListener. The example of ReadinessBloc can be seen on NetworkStatusWidget

Readiness Mixin

ReadinessMixin is an implementation of Readiness that is more general than ReadinessBloc so it can be used on other layers like domain, data, even on the bloc on the presentation layer. ReadinessMixin will add severeal functionalities to the class that is being used with, so that class is aware of the status change that happens inside Readiness. The implementation of ReadinessMixin is also using stream to provide realtime status change to the class. Below are the usage example of ReadinessMixin that implemented on AuthenticationBloc to handle offline login.

Setup

To use ReadinessMixin inside class, there are several setup that needs to be done first:

  1. Enrich the class with ReadinessMixin by using with syntax on class declaration.

  2. Inject Readiness as class dependency via the constructor.

  3. Call initReadiness, with readiness as a parameter to initialize.

  4. If the class has close/dispose method, put closeReadiness inside it.

Usage

There are 2 main API that can be used to handle the offline behavior of the code:

  1. isReady is a simple boolean value that can be refered to determine the flow of the code.

  2. callWhenReady can be used to queue your function call, so that it can be executed asynchronously after the ready condition is met.

Both of the API will refer to the default ready condition, which is when all of the status inside readiness is true. But for some cases when a custom ready condition is needed, you can provide custom readyWhen condition when calling initReadiness on the constructor.

Although most of the example given is on the presentation layer, ReadinessMixin technically can be used on other layers as well, please assess the requirement and the desired behavior for each journey since the expectation will be different.

Attachments:

carbon(2).png (image/png)
carbon(3).png (image/png)
Untitled Diagram.drawio(1).png (image/png)
carbon(4).png (image/png)
carbon(5).png (image/png)
carbon(6).png (image/png)
carbon(7).png (image/png)