Onboarding - application lifecycle
Managing the Application Lifecycle with OnboardingSession and OnboardingSessionManager
OnboardingSessionManager
can be a central point for an application to access OnboardingSession
, which contains all services required by the application to run properly, for example:
SAPURLSession
assigned to an authenticated user,- Secure credential store for sensitive information,
- OData services, etc.
OnboardingSession
can be used for common tasks, for instance:
- locking/unlocking the application,
- perform base operations, for example log upload,
- managing the passcode of the secure store using
StoreManager
.
OnboardingSession
can be created and used without OnboardingSessionManager
however the recommended way is to use it.
With OnboardingSessionManager
, the whole life cycle of an application can be supported:
- at first run, perform a user onboarding,
- locking the application UI (by hiding the application screens containing sensitive data) when the running application goes to background,
- unlocking the application UI (using passcode screen) when the application comes back to foreground,
- restoring the user onboarding session when the application has been restarted - and had been stopped in an onboarded state,
- removing the user onboarding session wiping all user related data.
The general set up, relation of the related components and participants, and the rule they have in the system is the following:
- Application uses
OnboardingSessionManager
to manage anOnboardingSession
and follow the application lifecycle changes. OnboardingSessionManager
- uses
OnboardingController
to manage theOnboardingSession
; opens anOnboardingFlow
which runs successfully, then converts the result to anOnboardingSession
. It is theOnboardingController
‘s concern to decide which flow should run - more precisely it is theOnboardingIDManaging
implementation assigned toOnboardingController
, - the session manager calls
OnboardingController
to remove an existing session, - it sets its state and calls appropriate delegate methods to manage UI in case the application goes to background or comes to foreground. The appropriate methods should be called by Application.
- The session manager does not manipulate the application UI directly. It makes changes related to the application UI using
OnboardingSessionManagerUIManaging
protocol, which should be implemented by application developers. This way application developers have full control over UI elements, and how they are being used - which view controller is presented for a particular action and how it is presented.
- uses
OnboardingController
- calls its onboarding ID manager to decide what kind of flow should be started: creating a new one using
onboard
or restoring an existing one usingrestore
. - then, calls the onboarding flow provider to provide the required flow. It must be implemented by application developers,
- finally, it performs the proper method on the flow.
- calls its onboarding ID manager to decide what kind of flow should be started: creating a new one using
Onboarding ID manager
should conform to theOnboardingIDManaging
protocol.- Implementation decides what flow should be started based on its state and supported functionality - and optionally based on user interaction (selection).
- It also has to store
OnboardingIDs
so they can be retrieved later after a restart.
Logging out
Log out can mean different things to different applications and there are more methods to support it. Different cases are:
- Log out from the server: invalidating the tokens while keeping data saved locally. In this case, a new request should trigger an authentication if the
SAPURLSession
is properly configured with authentication observers. - Log out locally, closing session, user switch: closing the onboarding session in the application making sure that the
SAPURLSession
and the secure store is not used. The session however remains on the device and can be restored with the common rules. A new onboarding session must be created to make the application usable:- an existing flow must be restored or
- a new flow should be created. If there is a previous session persisted, then it can be supported only when multi-user scenario is supported. For that, at least the
OnboardingIDManaging
inOnboardingController
should be replaced with a custom one,
- remove onboarding session: the session and all its local data will be removed from the device and cannot be restored.
Using OnboardingSession
, all the use-cases are supported.
- Log out on server: CPms supports log out functionality. It invlidates the authentication of the user. Call
OnboardingSession
’slogout
method. - Log out locally, closing the session: just release the reference to the
OnboardingSession
and create a new one. There is aninvalidate
method on theOnboardingSession
, which invalidates the session. Can be useful when the session is shared among objects to make sure it won’t be usable after it has been invalidated. UsingOnboardingSessionManager
, the easiest way is to callclose
which invalidates the existing session and then releases it. - Log out from server then locally: just perform the two steps mentioned above: call
logout
on the session then invalidate it. - Removing session: there can be two cases:
- there is a restored
OnboardingSession
. IfOnboardingSessionManager
is used, callremoveSession
on it. Otherwise, callresetFlow()
with the onboardingID of the session onOnboardingController
, then release the session. - a session should be removed which is not (or cannot be) restored: call
resetFlow(for:completionHandler:)
onOnboardingController
passing the appropriate onboardingID.
- there is a restored
Multi-User Support
SAPFioriFlows
also supports multi-user scenarios. Multi-user can mean different things in various contexts. An application might have multiple types of flows, or it can simply mean that a single flow is being used with more than one onboarded users – allowing each user to access their own data securely.
As an application developer, you are free to implement this use-case as desired. However, we recommend to use the OnboardingSessionManager
with a custom implementation of the OnboardingIDManaging
protocol – by default, we provide a SingleOnboardingIDManager
only, since multi-user scenarios can be more complex.
You can use many different sources of data structures to read, write and store your users’ OnboardingID
s. You might store them on the users’ device in the UserDefaults
, you may want to store them in the KeyChain or even in a database. It is up to the application developer to decide what suits their needs. For storing and removing data related to the OnboardingID
, you have to implement the store(onboardingID:completionHandler:)
and remove(onboardingID:completionHandler:)
methods.
Also, it is your concern to determine if you want to start an onboarding, restoring or resetting flow – in other words: how you want to implement flowToStart(completionHandler:)
– and what logic you wish to use for this purpose.
A simple way to do this is to check if an OnboardingID
already exists in your data set. If it does, you know you are dealing with a restore flow. Otherwise, you can return .onboard
as the flow to start. You can retrieve an OnboardingID
from the users by displaying a view controller where they can select an existing OnboardingID
or start a new session – resulting in a new OnboardingID
.
You will also have to provide some UI elements for the end-user where they can select a given OnboardingID
(if it exists), or create a new onboarding session – and connect this UI to your custom implementation of OnboardingIDManaging
.
-
Stores and manages one user’s OnboardingSession
See moreDeclaration
Swift
public class OnboardingSessionManager<T> where T : OnboardingSession
-
Stores information about an onboarding session Application developer can subclass OnboardingSession to add other app related meaningful properties or to set properties properly. For example when the SAPcpmsSettingsParameters is not stored using the default key in OnboardingContext then subclasses have to implement the code to provide the SAPcpmsSettingsParameters based on the used key
open class YourSession: OnboardingSession { var appURL: URL! var otherIntProperty: Int = 0 var appDict = [String: Any]() required public init(flow: OnboardingFlow) { super.init(flow: flow) // When SAPcpmsSettingsParameters is under another key self.settingsParameters = flow.context.info[.yourSettingsParameters] as? SAPcpmsSettingsParameters self.appURL = URL(string:"") self.otherIntProperty = 12 self.appDict = ["a":"b"] } }
When a custom
OnboardingInfoKey
needs to be used to store a custom value, then the correspondingOnboardingSession
subclass may be implemented as follows:
See morepublic extension OnboardingInfoKey { static let yourCustomOnboardingInfoKey = OnboardingInfoKey("yourCustomOnboardingInfoKey") } class CustomOnboardingStep: OnboardingStep{ func onboard(context: OnboardingContext, completionHandler: @escaping (OnboardingResult) -> Void) { var newContext = context // set value under newly added key inside Info dictionary newContext.info[.yourCustomOnboardingInfoKey] = "AnyStringValue" completionHandler(.success(newContext)) } func restore(context: OnboardingContext, completionHandler: @escaping (OnboardingResult) -> Void) { var newContext = context // set value under newly added key inside Info Dictionary newContext.info[.yourCustomOnboardingInfoKey] = "AnyStringValue" completionHandler(.success(newContext)) } func reset(context: OnboardingContext, completionHandler: @escaping () -> Void) { completionHandler() } } open class YourSession: OnboardingSession { var yourCustomProperty: Any = "" required public init(flow: OnboardingFlow) { super.init(flow: flow) // set value of custom property here yourCustomProperty = flow.context.info[.yourCustomOnboardingInfoKey] } } //Use the code below to access it OnboardingSessionManager.shared.onboardingSession?.yourCustomProperty
Declaration
Swift
open class OnboardingSession
-
Protocol for onboarding controller implementations, used by
See moreOnboardingSessionManager
Declaration
Swift
public protocol OnboardingControlling
-
Onboards or restores an OnboardingFlow based on the response of the given OnboardingIDManaging implementation.
See moreDeclaration
Swift
public class OnboardingController : OnboardingControlling
-
Implementers should manage the onboarding ID of the onboarding sesssions.
See moreDeclaration
Swift
public protocol OnboardingIDManaging : AnyObject