Onboarding - basics

Initialize the application so it can communicate with a backend system initially or upon app restart. The initialization process:

  • Retrieves the configuration from different sources. See Onboarding Configuration.
  • Authenticates using the selected authentication method to the application endpoint.
  • Sets up an SAPURLSession with all the necessary observers and authenticators.
  • Creates a store with the appropriate security to store all credentials and sensitive information gathered during the onboarding flow.

The Onboarding solution provided by the SAPFioriFlows framework includes customizable components that can be used together to meet the application’s specific requirements, and includes:

  1. Step
  2. Flow
  3. Offline Restore
  4. Modes of running the flow
  5. Presenting screens
  6. Running the flow: an example
  7. Using the Offline Restore flow

1. Step

The tasks necessary to achieve the onboarded state of the application are encapsulated in different classes called steps. Each step has a well defined task. The series of steps taken together is called the flow.

SAPFioriFlows includes several steps, each with different functionality. Steps can be grouped based on their functionality:

Use the flat dictionary with given keys (OnboardingInfoKey) also referred to as info, to pass data between steps.

If a step gathers any data that might be needed in the future, for example in case of a restart, it should be persisted physically in the store by the step itself. The step that requires this data can then load it when needed.

2. Flow

There are two types of flows based on the state of the application:

  • onboarding flow – The application starts from an initial state (the first run or after a reset)
  • restoring flow – The application starts, but a persisted state already exists

A flow can contain any number of steps appropriate for the application. The steps used in a flow can be in any order that makes sense for the application, and is not controlled by the SDK. It is up to the application developer to configure and set up the flows properly. Each step has its own set of arguments which are needed to perform its task.

A general onboarding flow consists of:

  • the WelcomeScreenStep which also gathers configuration and stores it in the store
  • an authentication step which configures the SAPURLSession with the appropriate observer and authenticator, performs the authentication
  • the SAPcpmsSettingsDownloadStep which gathers the settings (for example PasswordPolicy) from the SAPcpms
  • StoreManagerStep which creates the store

A general restoring flow contains the same steps but starts with the StoreManagerStep which opens the existing SecureStore:

  • StoreManagerStep: opens the SecureStore
  • WelcomeScreenStep reloads the configuration from the store
  • an authentication step
  • the SAPcpmsSettingsDownloadStep which gather the settings, for example PasswordPolicy

3. Offline Restore

Offline Restore can be useful in scenarios where the application is offline most of the time. Once the user has onboarded, it allows the application to restore data offline, without a network connection:

// Example with BasicAuthenticationStep
func basicAuthenticationStep() -> BasicAuthenticationStep {
let basicAuthenticationStep = BasicAuthenticationStep()
basicAuthenticationStep.sendsValidationRequest = ConnectivityUtils.isConnected() // determine if connected to the internet
return basicAuthenticationStep
}

let onboarding: [OnboardingStep] = [
<# Additional Steps #>
BasicAuthenticationStep(retryCount: 4),
<# Additional Steps #>
]

let restoring: [OnboardingStep] = [
<# Additional Steps #>
basicAuthenticationStep(),
<# Additional Steps #>
]

4. Modes of running the flow

You can implement your own steps, or implement steps included in the SAPFioriFlows framework.

There are two ways to use the steps provided by the framework:

Usually the steps are implemented in a way where the automatic methods call the manual method internally so the methods behavior is guaranteed to be the same.

See OAuth2AuthenticationStep for an example. It declares a low-level onboard method and a higher-level onboard method (which conforms to OnboardingStep protocol supporting automatic flow management):

// 'automatic' flow management method conforming to `OnboardingStep`
public func onboard(context: OnboardingContext, completionHandler: @escaping (OnboardingResult) -> Void)

// 'manual' flow management method: lists the properties the step needs
open func onboard(authenticationURL: URL, authenticationParameters: OAuth2AuthenticationParameters, sapURLSession: SAPURLSession, credentialStore: CodableStoring, presentationDelegate: FlowPresentationDelegate, completionHandler: @escaping (Error?) -> Void)

5. Presenting screens

The application can present a splash screen when the onboarding flow starts. This screen hides the application screen between the steps and also provides a consistent background for the onboarding flow. There are more splash screen use-cases. In every case, the developer must handle when to present the screen before the onboarding flow starts and dismiss the screen when the flow finishes.

  1. There is no splash screen set to PresentationDelegate The application screen is observable for a moment every time it moves between onboarding steps. If the app presents its splash screen before the onboarding flow starts, it will be visible. That screen can be replaced by the appropriate application screen at the end of the onboarding flow.

  2. The application starts with InfoViewController as a root view controller: this can be set as a splash screen to the ModalUIViewControllerPresenter (when it is used as PresentationDelegate - default) and will be visible instead of the application screen when moving between steps. The information text on the screen will be updated by the steps automatically. The developer must replace it with the application view controllers at the end of the onboarding flow:

    // instantiate the splashScreen, set it to `presentationDelegate` then start the flow
    let splashScreen = FUIInfoViewController.createSplashScreenInstanceFromStoryboard()
    <# Set it as the rootViewController #>
    // set as splash for onboarding
    presentationDelegate.setSplashScreen(splashScreen)
    
    <# run the onboarding or restoring flow #>
    
    // when the onboarding flow was successful, clear the splash screen
    (context.presentationDelegate as! ModalUIViewControllerPresenter).presentationDelegate.clearSplashScreen()
    

    You can use any custom ViewController as a splash screen if it conforms to the InfoTextSettable protocol, which can be implemented as an extension to any existing ViewController.

  3. When starting the application, the main application screen is visible, then a splash screen must be opened over the application screen using the present method of the FlowPresentationDelegate. This splash screen is visible when switching between steps. The information text on the screen will be updated by the steps automatically. You must add code to close the screen by calling dismiss on the PresentationDelegate after the onboarding flow finishes:

    // instantiate the splashScreen, call present on presentationDelegate, then in callback start the flow
    let splashScreen = FUIInfoViewController.createSplashScreenInstanceFromStoryboard()
    presentationDelegate.present(splashScreen) { _ in
      <# run the onboarding or restoring flow #>
    }
    
    // when the onboarding flow was successful, call dismiss on presentationDelegate
    context.presentationDelegate.dismiss { _ in
    }
    

Note: By default, the ModalUIViewControllerPresenter overrides the modalPresentationStyle property of the presented view controllers to .overFullScreen. This makes it possible to correctly present view controllers on top of everything, including UIAlertController. However when using this presentation style, some of the underlying view controller’s methods (viewWillDisappear, viewWillAppear) will not be called when they are hidden / shown again. You can change the default presentation style any time on ModalUIViewControllerPresenter.

6. Running the flow: an example

As described in Flow and Modes of running the flow sections, the following sample presents a general way of running an onboarding and restoring flow:

let presentationDelegate = ModalUIViewControllerPresenter()
<# Initialize, present and set the splash screen #>
presentationDelegate.setSplashScreen(<# your splash screen instance #>)
onboardOrRestore() // start the proper flow

func onboardOrRestore() {

    // declare the steps: you can use different instances as well for the onboarding/restoring flows
    let welcome = WelcomeScreenStep(providers: [<# list your configuration providers #>]) // welcome and configuration management
    let sessionConf = SAPcpmsSessionConfigurationStep() // SAPcpms compatibility
    let auth = OAuth2AuthenticationStep() // authentication
    let settings = SAPcpmsSettingsDownloadStep() // download and apply the settings
    let store = StoreManagerStep() // store management

    // initialize context
    var context = OnboardingContext(presentationDelegate: presentationDelegate)
    let onboardingFlow: [OnboardingStep] = [welcome, sessionConf, auth, settings, store]
    let restoringFlow: [OnboardingStep] = [store, welcome, sessionConf, auth, settings]

    if let savedUUIDString = UserDefaults.standard.string(forKey: "userOnboardingID"), let uuid = UUID(uuidString: savedUUIDString) {
        context.onboardingID = uuid
        OnboardingFlowController.restore(on: restoringFlow, context: context) { result
        <# handle the result, start the application logic #>
        }
    } else {
        OnboardingFlowController.onboard(on: onboardingFlow, context: context) { result
            <#handle the result and persist the onboardingID in case of success #>

            UserDefaults.standard.set(context.onboardingID.uuidString, forKey:"userOnboardingID")

            <# Save the required properties from the context to your app: SAPURLSession, Store, etc. Never save the whole context! #>

            <# start the application logic #>
        }
    }
}

Note: A production application is more complicated and must properly handle error and success cases. Use the SAP Cloud Platform SDK for iOS Assistant to generate a more detailed sample application.

7. Using the Offline Restore flow

The following example shows you how to use the offline restore functionality with SAPFoundation‘s ConnectivityObserver to synchronize cloud application state at runtime.

First, let’s define a synching flow which consists of the following OnboardingSteps. You may customize yours.

let synching: [OnboardingStep] = [
    WelcomeScreenStep(), // configure if necessary
    SAPcpmsSettingsDownloadStep(), 
    SAPcpmsDestinationsDownloadStep(),
    SAPcpmsLogSettingsApplyStep(), 
    SAPcpmsUsagePolicyApplyStep(), 
    PasscodePolicyApplyStep(), 
    SAPcpmsLockWipePolicyApplyStep()
]

Add the following code snippet to your class’s initializer:

ConnectivityReceiver.registerObserver(self)

Then, let’s confirm to the ConnectivityObserver protocol by implementing its methods.

func connectionEstablished() {
    print("Network connection detected.")
}

func connectionChanged(_ previousReachabilityType: ReachabilityType, reachabilityType: ReachabilityType) {
    print("Network connection status changed.")
    if case previousReachabilityType = ReachabilityType.offline {
        do {
            // run your snyhcronizing flow
        } catch {
            print("Could not synchronize after connectionChanged(previousReachabilityType:reachabilityType:)")
        }
    }
}

func connectionLost() {
    print("Network connection lost.")
}
  • Onboarding step implementation of Basic Authentication Used in the onboarding/restoring flow, this step is responsible to configure the app’s URLSession to be able to communicate with basic authentication protected resources. Creates and registers the BasicAuthenticationObserver to the SAPURLSession, then sends a validation request which will trigger an authentication flow.

    Customization

    During the onboarding flow, if there is a splash screen which shows a text, that text can be changed/localized.

    // The customized WelcomeStep can be created like the following code snippet
    func customBasicAuthStep() -> OnboardingStep {
       let basicAuthenticationBundle = Bundle(for: BasicAuthenticationStep.self)
    
       let localizedInfoScreenText = NSLocalizedString("BasicInfoScreenText", tableName: "Example Table name", bundle: basicAuthenticationBundle, value: "Validating Basic credentials", comment: "")
       let localizedCancelButtonText = NSLocalizedString("CancelButtonText", tableName: "Example Table name", bundle: basicAuthenticationBundle, value: "Cancel", comment: "")
       let localizedInformationLabelText = NSLocalizedString("BasicInformationLabelTextKey", tableName: "Example Table name", bundle: basicAuthenticationBundle, value: "Authentication", comment: "")
       let localizedHeadLineLabelText = NSLocalizedString("BasicHeadLineLabelTextKey", tableName: "Example Table name", bundle: basicAuthenticationBundle, value: "Please enter your credentials", comment: "")
       let localizedSignInButtonText = NSLocalizedString("BasicSignInButtonText", tableName: "Example Table name", bundle: basicAuthenticationBundle, value: "Sign In", comment: "")
       let localizedUsernamePlaceholderText = NSLocalizedString("BasicUsernamePlaceholderTextKey", tableName: "Example Table name", bundle: basicAuthenticationBundle, value: "Username", comment: "")
       let localizedPasswordPlaceholderText = NSLocalizedString("BasicPasswordPlaceholderTextKey", tableName: "Example Table name", bundle: basicAuthenticationBundle, value: "Password", comment: "")
    
       let presenter = FioriBasicCredentialsViewControllerPresenter()
       presenter.basicViewControllerConfigurationHandler = { basicView in
            basicView.headlineLabel.text = localizedHeadLineLabelText
            basicView.informationLabel.text = localizedInformationLabelText
            basicView.signInButton.titleLabel?.text = localizedSignInButtonText
            basicView.usernameTextField.emailTextField.placeholder = localizedUsernamePlaceholderText
            basicView.passwordTextField.emailTextField.placeholder = localizedPasswordPlaceholderText
            basicView.navigationItem.leftBarButtonItem?.title = localizedCancelButtonText
       }
       let step = BasicAuthenticationStep(presenter: presenter)
       step.infoScreenText = localizedInfoScreenText
    
       return step
    }
    
    See more

    Declaration

    Swift

    open class BasicAuthenticationStep : OnboardingStep
  • Manages the End User License Agreement (EULA) handling. The EULA version will be stored in the credentialStore of the OnboardingContext which is used to decide if a new EULA screen should be presented on the next run. If the user has not confirmed EULA, or a new EULA content is present, a screen will be displayed to request user confirmation.

    Usage

    let title = "SAP - EULA"
    let text = """
    This is a legally binding agreement (Agreement) between Company and SAP SE which provides the terms of your use of the SAP mobile application (Software). By clicking "Accept" or by installing and/or using the Software, you on behalf of the Company are agreeing to all of the terms and conditions stated in this Agreement. If you do not agree to these terms, do not click "Agree", and do not use the Software. You represent and warrant that you have the authority to bind the Company to the terms of this Agreement.
    """
    let attributes = [NSAttributedStringKey.font: UIFont(name: "Georgia", size: 17.0)!]
    let content = NSAttributedString(string: content, attributes: attributes)
    let eulaContent = EULAContent(title: title, content: content, version: "1.0")
    let eulaStep = EULAStep(eulaContent: eulaContent)
    
    See more

    Declaration

    Swift

    open class EULAStep : OnboardingStep, FUIEULADelegate
  • The content of the EULA screen. Contains a title and an NSAttributedString as the content value.

    See more

    Declaration

    Swift

    public struct EULAContent
  • Instantiates an OnboardingStep capable of registering the LanguageObserver in the onboard / restore flow.

    If you wish to use this funcionality in manual mode, you can use this one-liner instead of this class:

    sapURLSession.register(LanguageObserver())
    
    See more

    Declaration

    Swift

    open class LanguageObserverConfigurationStep : SimpleTaskStep
  • Instantiates an OnboardingStep capable of registering the CorrelationObserver observer in the onboard / restore flow.

    If you wish to use this funcionality in manual mode, you can use this one-liner instead of this class:

    let sapURLSession = <#SAPURLSession#>
    sapURLSession.register(<#CorrelationObserver#>)
    
    See more

    Declaration

    Swift

    open class SAPcpmsCorrelationConfigurationStep : SimpleTaskStep
  • Instantiates an OnboardingStep capable of registering the SAPcpmsUserBlockedObserver observer in the onboard / restore flow.

    If you wish to use this funcionality in manual mode, you can use this one-liner instead of this class:

    let sapURLSession = <#SAPURLSession#>
    sapURLSession.register(<#SAPcpmsUserBlockedObserver#>)
    
    See more

    Declaration

    Swift

    open class SAPcpmsUserBlockedConfigurationStep : SimpleTaskStep
  • Instantiates an OnboardingStep capable of applying the NUIStyleSheet in the onboard / restore flow.

    If you wish to use this funcionality in manual mode, you can use this one-liner instead of this class:

    NUISettings.loadStylesheetByURL(url: <#URL#>)
    
    See more

    Declaration

    Swift

    open class NUIStyleSheetApplyStep : SimpleTaskStep
  • OAuth 2.0 onboarding step.

    Used in the onboarding / restoring flow, this step is responsible to configure the app’s URLSession to be able to communicate with OAuth 2.0 protected resources. Creates and registers the OAuth2Observer to the SAPURLSession, then sends a validation request which will trigger an authentication flow.

    Customization

    During the onboarding flow, if there is a splash screen which shows a text, that text can be changed/localized. The presented webView will also have localizable components, but the localization of downloaded data depends on the server and is not customizable from the created client application.

    func customOauth2AuthStep() -> OnboardingStep {
       let oauth2Bundle = Bundle(for: OAuth2AuthenticationStep.self)
    
       let localizedInfoScreenText = NSLocalizedString("Oauth2InfoScreenText", tableName: "Example Table name", bundle: oauth2Bundle, value: "Validating OAuth2 credentials", comment: "")
       let localizedCancelButtonText = NSLocalizedString("CancelButtonText", tableName: "Example Table name", bundle: oauth2Bundle, value: "Cancel", comment: "")
    
       let presenter = FioriUIWebViewPresenter()
       presenter.webViewControllerConfigurationHandler = { webView in
           webView.cancelButton?.title = localizedCancelButtonText
    
           return webView
       }
    
       let step = OAuth2AuthenticationStep(presenter: presenter)
       step.infoScreenText = localizedInfoScreenText
    
       return step
    }
    
    See more

    Declaration

    Swift

    open class OAuth2AuthenticationStep : OnboardingStep
  • OnboardingStep Represents a step in the onboarding/restoring flow.

    See more

    Declaration

    Swift

    public protocol OnboardingStep : AnyObject
  • Implementers must present appripriately the ViewControllers provided by the onboarding steps Different implementers can present the ViewControllers differently but must be appropriate for the ViewController design of the used steps. For example if a step uses a ViewController designed to use NavigationController the presenter must put the ViewController into a NavigationController

    See more

    Declaration

    Swift

    public protocol FlowPresentationDelegate : AnyObject
  • Implementers must use the presentationDelegate to present their ViewControllers

    See more

    Declaration

    Swift

    public protocol FlowPresentationDelegateClient : AnyObject
  • Implementers must set the text of the presented infoscreen

    See more

    Declaration

    Swift

    public protocol InfoTextSettable
  • OTP onboarding step.

    Used in the onboarding / restoring flow, this step is responsible to configure the app’s URLSession to be able to communicate with OTP protected resources. Creates and registers the OTPObserver. This step should be set before the authentication step (can be used with Basic, OAuth 2.0 and SAML 2.0 authentications).

    Customization

    During the onboarding flow, if there is a splash screen which shows a text, that text can be changed/localized. The presented webView will also have localizable components, but the localization of downloaded data depends on the server and is not customizable from the created client application.

    func customSAMLAuthStep() -> OnboardingStep {
       let samlBundle = Bundle(for: SAMLAuthenticationStep.self)
    
       let localizedInfoScreenText = NSLocalizedString("SAMLInfoScreenText", tableName: "Example Table name", bundle: samlBundle, value: "Validating SAML credentials", comment: "")
       let localizedCancelButtonText = NSLocalizedString("CancelButtonText", tableName: "Example Table name", bundle: samlBundle, value: "Cancel", comment: "")
    
       let presenter = FioriUIWebViewPresenter()
       presenter.webViewControllerConfigurationHandler = { webView in
           webView.cancelButton?.title = localizedCancelButtonText
    
           return webView
       }
    
       let step = SAMLAuthenticationStep(presenter: presenter)
       step.infoScreenText = localizedInfoScreenText
    
       return step
    }
    
    See more

    Declaration

    Swift

    open class OTPSessionConfigurationStep : OnboardingStep
  • SAML 2.0 onboarding step.

    Used in the onboarding / restoring flow, this step is responsible to configure the app’s URLSession to be able to communicate with SAML 2.0 protected resources. Creates and registers the SAMLObserver to the SAPURLSession, then sends a validation request which will trigger an authentication flow.

    Customization

    During the onboarding flow, if there is a splash screen which shows a text, that text can be changed/localized. The presented webView will also have localizable components, but the localization of downloaded data depends on the server and is not customizable from the created client application.

    func customSAMLAuthStep() -> OnboardingStep {
       let samlBundle = Bundle(for: SAMLAuthenticationStep.self)
    
       let localizedInfoScreenText = NSLocalizedString("SAMLInfoScreenText", tableName: "Example Table name", bundle: samlBundle, value: "Validating SAML credentials", comment: "")
       let localizedCancelButtonText = NSLocalizedString("CancelButtonText", tableName: "Example Table name", bundle: samlBundle, value: "Cancel", comment: "")
    
       let presenter = FioriUIWebViewPresenter()
       presenter.webViewControllerConfigurationHandler = { webView in
           webView.cancelButton?.title = localizedCancelButtonText
    
           return webView
       }
    
       let step = SAMLAuthenticationStep(presenter: presenter)
       step.infoScreenText = localizedInfoScreenText
    
       return step
    }
    
    See more

    Declaration

    Swift

    open class SAMLAuthenticationStep : OnboardingStep
  • Class for SAPcpmsClientResources download onboarding step handling

    Customization

    During the onboarding flow, if there is a splash screen which shows a text, that text can be changed/localized.

    
    // The localized SAPcpmsClientResourcesDownloadStep can be created like the following code snippet
    func customClientResourcesDownloadStep() -> OnboardingStep {
       let step = SAPcpmsClientResourcesDownloadStep()
    
       let sapcpmsClientResourcesDownloadStep = Bundle(for: SAPcpmsClientResourcesDownloadStep.self)
       step.infoScreenText = NSLocalizedString("SAPcpmsClientResourcesDownloadInfoScreenTextKey", tableName: "ExampleTableName", bundle: sapcpmsDestinationDownloadBundle, value: "Example Info Screen Text", comment: "")
    
       return step
    }
    
    
    See more

    Declaration

    Swift

    open class SAPcpmsClientResourcesDownloadStep : OnboardingStep
  • Class for SAPcpmsDestinations download onboarding step handling

    Customization

    During the onboarding flow, if there is a splash screen which shows a text, that text can be changed/localized.

    
    // The localized SAPcpmsDestinationsDownloadStep can be created like the following code snippet
    func customDestinationsDownloadStep() -> OnboardingStep {
       let step = SAPcpmsDestinationsDownloadStep()
    
       let sapcpmsDestinationsDownloadStep = Bundle(for: SAPcpmsDestinationsDownloadStep.self)
       step.infoScreenText = NSLocalizedString("SAPcpmsDestinationsDownloadInfoScreenTextKey", tableName: "ExampleTableName", bundle: sapcpmsDestinationDownloadBundle, value: "Example Info Screen Text", comment: "")
    
       return step
    }
    
    
    See more

    Declaration

    Swift

    open class SAPcpmsDestinationsDownloadStep : OnboardingStep
  • Instantiates an OnboardingStep capable of applying the SAPcpmsLockWipePolicy parameters in the onboard / restore flow. The SAPcpmsSettings (downloaded form mobile services) contains a blockWipingPolicy part. This policy can be enabeled/disabled depending on mobile services settings. The policy contains the blockDisconnectedPeriod and wipeDisconnectedPeriod integer values. E.g.: blockWipingPolicy: { blockWipeEnabled: true, blockDisconnectedPeriod: 1, wipeDisconnectedPeriod: 20 } The lock disconnected period describes after how many days should lock the user. The wipe disconnected period describes after how many days should wipe the user. The start date of the calculation is based on the last successful server communication. Prerequisite: the SAPcpmsSettingsDownloadStep should be in the flow before the SAPcpmsLockWipePolicyApplyStep. The step fails with SAPcpmsLockWipePolicyError if the user should lock or wipe by the application or if an internal error occurs. If SAPcpmsLockWipePolicy and stored Date exists the step checks the dates If SAPcpmsLockWipePolicy exists and stored Date doesn’t exist the step stores the current date and checks the dates If SAPcpmsLockWipePolicy doesn’t exist and stored Date exists the step deletes the date If SAPcpmsLockWipePolicy and stored Date doesn’t exist the step doesn’t do anything

    See more

    Declaration

    Swift

    open class SAPcpmsLockWipePolicyApplyStep : OnboardingStep
  • Instantiates an OnboardingStep capable of applying the SAPcpmsLogSettings parameters in the onboard / restore flow.

    If you wish to use this funcionality in manual mode, you can use this one-liner instead of this class:

    Logger.root.apply(sapcpmsLogSettings: <#SAPcpmsLogSettings#>)
    
    See more

    Declaration

    Swift

    open class SAPcpmsLogSettingsApplyStep : SimpleTaskStep
  • Instantiates an OnboardingStep capable of registering the SAPcpmsObserver observer in the onboard / restore flow.

    If you wish to use this funcionality in manual mode, you can use this one-liner instead of this class:

    let sapURLSession = <#SAPURLSession#>
    sapURLSession.register(<#SAPcpmsObserver#>)
    
    See more

    Declaration

    Swift

    open class SAPcpmsSessionConfigurationStep : SimpleTaskStep
  • Class for SAPcpmsSettings download onboarding step handling

    Customization

    During the onboarding flow, if there is a splash screen which shows a text, that text can be changed/localized.

    
    // The localized SAPcpmsSettingsDownloadStep can be created like the following code snippet
    func customSettingsDownloadStep() -> OnboardingStep {
       let step = SAPcpmsSettingsDownloadStep()
    
       let sapcpmsSettingsDownloadBundle = Bundle(for: SAPcpmsSettingsDownloadStep.self)
       step.infoScreenText = NSLocalizedString("SAPcpmsSettingsDownloadInfoScreenTextKey", tableName: "ExampleTableName", bundle: sapcpmsSettingsDownloadBundle, value: "Example Info Screen Text", comment: "")
    
       return step
    }
    
    
    See more

    Declaration

    Swift

    open class SAPcpmsSettingsDownloadStep : OnboardingStep
  • Onboarding step implementation of SAPcpmsUserIdentityDiscovery Authentication Used in the onboarding/restoring flow, this step is responsible to configure the app’s URLSession to be able to communicate with SAPcpmsUserIdentityDiscovery authentication protected resources. Creates and registers the UserIdentityObserver to the SAPURLSession, then sends a validation request which will trigger an authentication flow.

    Customization

    During the onboarding flow, if there is a splash screen which shows a text, that text can be changed/localized. The presented webView will also have localizable components, but the localization of downloaded data depends on the server and is not customizable from the created client application.

    
    //The localized SAPcpmsUserIdentityDiscoveryAuthenticationStep can be created like the following code snippet
    func customSAPcpmsUserIdentityDiscoveryAuthenticationStep() -> OnboardingStep {
       let step = SAPcpmsUserIdentityDiscoveryAuthenticationStep()
    
       let userIdentityDiscoveryAuthenticationBundle = Bundle(for: SAPcpmsUserIdentityDiscoveryAuthenticationStep.self)
       step.infoScreenText = NSLocalizedString("UserIdentityDiscoveryInfoScreenTextKey", tableName: "ExampleTableName", bundle: userIdentityDiscoveryAuthenticationBundle, value: "Example Info Screen Text", comment: "")
    
       return step
    }
    
    
    See more

    Declaration

    Swift

    open class SAPcpmsUserIdentityDiscoveryAuthenticationStep : OnboardingStep
  • This step is capable of integrating a simple functionality into the onboarding flow, without the need to implement the whole OnboardingStep protocol. Provides a convenient way of using the same piece of logic for both onboard and restore processes.

    See more

    Declaration

    Swift

    open class SimpleTaskStep : OnboardingStep
  • Onboarding step implementation of SLS certificate authentication Used in the onboarding/restoring flow, this step is responsible to configure the app’s URLSession to be able to communicate with SLS authentication protected resources. Creates and registers the UserIdentityObserver to the SAPURLSession, then sends a validation request which will trigger an authentication flow.

    Customization

    During the onboarding flow, if there is a splash screen which shows a text, that text can be changed/localized.

    // The customized WelcomeStep can be created like the following code snippet
    func customSLSAuthStep() -> OnboardingStep {
       let slsAuthenticationBundle = Bundle(for: SLSAuthenticationStep.self)
    
       let localizedInfoScreenText = NSLocalizedString("SLSInfoScreenText", tableName: "Example Table name", bundle: slsAuthenticationBundle, value: "Validating credentials", comment: "")
       let localizedCancelButtonText = NSLocalizedString("CancelButtonText", tableName: "Example Table name", bundle: slsAuthenticationBundle, value: "Cancel", comment: "")
       let localizedInformationLabelText = NSLocalizedString("SLSInformationLabelTextKey", tableName: "Example Table name", bundle: slsAuthenticationBundle, value: "Please enter your credentials", comment: "")
       let localizedSignInButtonText = NSLocalizedString("SLSSignInButtonText", tableName: "Example Table name", bundle: slsAuthenticationBundle, value: "Sign In", comment: "")
    
       let presenter = SLSLoginInputPresenter()
       presenter.loginViewControllerConfigurationHandler = { viewController in
            viewController.informationLabel.text = localizedInformationLabelText
            viewController.navigationItem.leftBarButtonItem?.title = localizedCancelButtonText
            viewController.navigationItem.rightBarButtonItem?.title = localizedSignInButtonText
       }
       let step = SLSAuthenticationStep(slsLoginInputPresenter: presenter)
       step.infoScreenText = localizedInfoScreenText
    
       return step
    }
    
    See more

    Declaration

    Swift

    open class SLSAuthenticationStep : OnboardingStep
  • let mpTitle1 = Data Privacy let mpText1 = Detailed text about how data privacy pertains to this app and why it is important for the user to enable this functionality let mpActionTitle1 = Learn more about Data Privacy var mpPageContent1 = UserConsentPageContent() mpPageContent1.title = mpTitle1 mpPageContent1.body = mpText1 mpPageContent1.actionTitle = mpActionTitle1 mpPageContent1.actionHandler = { controller in let alert = UIAlertController(title: Data Privacy, message: Alert for Data Privacy Page, preferredStyle: UIAlertControllerStyle.alert) alert.addAction(UIAlertAction(title: OK, style: UIAlertActionStyle.default, handler: nil)) controller.present(alert, animated: true, completion: nil) } let mpTitle2 = Security let mpText2 = Detailed text about how data privacy pertains to this app and why it is important for the user to enable this functionality let mpActionTitle2 = Learn more about Data Privacy var mpPageContent2 = UserConsentPageContent() mpPageContent2.title = mpTitle2 mpPageContent2.body = mpText2 mpPageContent2.actionTitle = mpActionTitle2 // When both url and action handler are set, the action handler takes precedence. mpPageContent2.actionUrl = http://www.sap.com mpPageContent2.actionHandler = { controller in let alert = UIAlertController(title: Data Privacy, message: Alert for Data Privacy Page, preferredStyle: UIAlertControllerStyle.alert) alert.addAction(UIAlertAction(title: OK, style: UIAlertActionStyle.default, handler: nil)) controller.present(alert, animated: true, completion: nil) } let mpTitle3 = Consent let mpText3 = Detailed text about how data privacy pertains to this app and why it is important for the user to enable this functionality let mpActionTitle3 = Learn more about Data Privacy var mpPageContent3 = UserConsentPageContent() mpPageContent3.title = mpTitle3 // It is possible to provide attributed text to enable adding developer defined attributes to the text other than the default. // Eg. change the font type to Georgia and size to 17.0 for the body. This can be done for the title and actionTitle as well , using the // titleAttributedText and actionTitleAttributedText respectively. When both body and bodyAttributedText are provided , the // attributedtext version takes precedence. // let mpAttributes3 = [NSAttributedStringKey.font: UIFont(name: Georgia, size: 17.0)!] // let mpBody3 = NSAttributedString(string: mpText3, attributes: mpAttributes3) // mpPageContent3.bodyAttributedText = mpBody3 mpPageContent3.body = mpText3 mpPageContent3.actionTitle = mpActionTitle3 let mpFormContent = UserConsentFormContent( version: one,isRequired: true,pages: [mpPageContent1, mpPageContent2, mpPageContent3]) let userConsentStep = UserConsentStep(userConsentFormsContent:[spFormContent, mpFormContent])

    See more

    Declaration

    Swift

    open class UserConsentStep : OnboardingStep, FUIUserConsentViewControllerDelegate
  • // The content of User Consent Forms.

    See more

    Declaration

    Swift

    public struct UserConsentFormContent
  • // The contents of a user consent page in a form. Each page corresponds to a screen displayed the user. A form can consist of one page or multiple pages that get displayed when the form is presented.

    See more

    Declaration

    Swift

    public struct UserConsentPageContent
  • Class for Welcome Screen onboarding step handling UI elements of the Welcome Screen are localizable through the step’s welcomeScreenCustomizationHandler which will be called during the WelcomeStep onboarding process to configure the screen.

    ## Customization

    
     // The customized WelcomeStep can be created like the following code snippet
     func configuredWelcomeScreenStep() -> WelcomeScreenStep {
        let discoveryConfigurationTransformer = DiscoveryServiceConfigurationTransformer(applicationID: "sample.application.id", authenticationPath: "sample.application.id")
        let welcomeScreen = WelcomeScreenStep(transformer: discoveryConfigurationTransformer, providers: [FileConfigurationProvider()])
    
       let welcomeScreenBundle = Bundle(for: WelcomeScreenStep.self)
       let localizedHeadlineLabelText = NSLocalizedString("WelcomeScreenHeadlineLabelKey", tableName: "ExampleTableName", bundle: welcomeScreenBundle, value: "Example Headline Text", comment: "")
       let localizedDetailLabelText = NSLocalizedString("WelcomeScreenDetailLabelKey", tableName: "ExampleTableName", bundle: welcomeScreenBundle, value: "Example Headline Text", comment: "")
       let localizedPrimaryActionButtonText = NSLocalizedString("WelcomeScreenPrimaryActionButtonTextKey", tableName: "ExampleTableName", bundle: welcomeScreenBundle, value: "Example Headline Text", comment: "")
       let localizedFootnoteActionButtonTitleText = NSLocalizedString("WelcomeScreenFootnoteActionButtonTextKey", tableName: "ExampleTableName", bundle: welcomeScreenBundle, value: "Example Headline Text", comment: "")
       let localizedFootnoteLabelText = NSLocalizedString("WelcomeScreenFootnoteLabelTextKey", tableName: "ExampleTableName", bundle: welcomeScreenBundle, value: "Example Headline Text", comment: "")
    
       welcomeScreen.welcomeScreenCustomizationHandler = { welcomeScreen in
           welcomeScreen.headlineLabel.text = localizedHeadlineLabelText
           welcomeScreen.detailLabel.text = localizedDetailLabelText
           welcomeScreen.primaryActionButton.titleLabel?.text = localizedPrimaryActionButtonText
           welcomeScreen.footnoteActionButton.setTitle(localizedFootnoteActionButtonTitleText, for: .normal)
           welcomeScreen.footnoteLabel.text = localizedFootnoteLabelText
       }
    
       return welcomeScreen
     }
    
    
    See more

    Declaration

    Swift

    open class WelcomeScreenStep : OnboardingStep, FUIWelcomeControllerDelegate, FUIOnboardingScanViewControllerDelegate
  • Declaration

    Swift

    class FUIOnboardingScanConfirmView : NibDesignable
  • Declaration

    Swift

    class FUIWelcomeScreen : FUIWelcomeController, UITextFieldDelegate
  • WelcomeScreen Error enum if demo mode button selected

    See more

    Declaration

    Swift

    public enum WelcomeScreenError : Error
  • Enable customization of activation screen UI components

    See more

    Declaration

    Swift

    public protocol ActivationStepUI
  • Enable customization of ScanConfirmView UI components

    See more

    Declaration

    Swift

    public protocol ScanConfirmViewUI : AnyObject
  • Enable customization of welcome screen UI components

    See more

    Declaration

    Swift

    public protocol WelcomeStepUI : AnyObject
  • The default implementation for the ASWebAuthenticationSessionPresenting. Presents a ASWebAuthenticationSession on demand, can be configured to show an info screen before the presentation.

    See more

    Declaration

    Swift

    @available(iOS 12.0, *)
    open class FioriASWebAuthenticationSessionPresenter : ASWebAuthenticationSessionPresenting, FlowPresentationDelegateClient
  • The default implementation for the SFAuthenticationSessionPresenting. Presents a SFAuthenticationSession on demand, can be configured to show an info screen before the presentation. If the callbackURLScheme is not set, the application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool func will be used

    See more

    Declaration

    Swift

    @available(iOS 11.0, *)
    open class FioriSFAuthenticationSessionPresenter : SFAuthenticationSessionPresenting, FlowPresentationDelegateClient
  • The default implementation for the SFSafariViewControllerPresenting. Presents a SFSafariViewController on demand, can be configured to show an info screen before the presentation.

    See more

    Declaration

    Swift

    open class FioriSFSafariViewControllerPresenter : NSObject, SFSafariViewControllerPresenting, FlowPresentationDelegateClient
  • This FlowPresentationDelegate implementation handles the screen presentation in such a way, that every present call results in a modal presentation on the top-most view controller.

    Important: This implementation requires that every present call have their own dismiss call pair. Self dismissing view controllers such as UIAlertControllers are not supported.

    See more

    Declaration

    Swift

    open class ModalUIViewControllerPresenter : FlowPresentationDelegate
  • Initializes SAPcpms Settings Password Policy from config file

    See more

    Declaration

    Swift

    struct FUIPasscodePolicy
  • Keys defined to access objects in a dictionary a typed way To extend the available keys define your own key the following way

     public extension OnboardingInfoKey {
         public static let myDeclaredKey = OnboardingInfoKey("myDeclaredKey")
    }
    

    Then you can use this to access information in the Dictionary

     var info = [OnboardingInfoKey: Any]()
     info[.myDeclaredKey] = MyStruct()
    
    See more

    Declaration

    Swift

    public struct OnboardingInfoKey : RawRepresentable, Equatable, Hashable, CustomStringConvertible, CustomDebugStringConvertible
  • Enum to handle errors in EULAStep

    See more

    Declaration

    Swift

    public enum EULAError : Error
  • Enum for presentation errors

    • failed: presentation failed
    • missing: viewcontroller is missing
    • cancelled: presentation cancelled
    See more

    Declaration

    Swift

    public enum FioriPresenterError : Error
  • Enum to handle errors in UserConsentStep

    See more

    Declaration

    Swift

    public enum UserConsentError : Error