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 an OnboardingSession and follow the application lifecycle changes.
  • OnboardingSessionManager
    • uses OnboardingController to manage the OnboardingSession; opens an OnboardingFlow which runs successfully, then converts the result to an OnboardingSession. It is the OnboardingController‘s concern to decide which flow should run - more precisely it is the OnboardingIDManaging implementation assigned to OnboardingController,
    • 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.
  • 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 using restore.
    • 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.
  • Onboarding ID manager should conform to the OnboardingIDManaging 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 in OnboardingController 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’s logout method.
  • Log out locally, closing the session: just release the reference to the OnboardingSession and create a new one. There is an invalidate method on the OnboardingSession, 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. Using OnboardingSessionManager, the easiest way is to call close 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:

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’ OnboardingIDs. 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 more

    Declaration

    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 corresponding OnboardingSession subclass may be implemented as follows:

    public 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
    
    See more

    Declaration

    Swift

    open class OnboardingSession
  • Protocol for onboarding controller implementations, used by OnboardingSessionManager

    See more

    Declaration

    Swift

    public protocol OnboardingControlling
  • Onboards or restores an OnboardingFlow based on the response of the given OnboardingIDManaging implementation.

    See more

    Declaration

    Swift

    public class OnboardingController : OnboardingControlling
  • Implementers should manage the onboarding ID of the onboarding sesssions.

    See more

    Declaration

    Swift

    public protocol OnboardingIDManaging : AnyObject