Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
Showing results for 
Search instead for 
Did you mean: 
Product and Topic Expert
Product and Topic Expert

Recently the engineering team behind the SAP BTP SDK for iOS received questions from app developers on how to use SAPFioriFlows and its predefined onboarding steps except using the WelcomeScreenStep.

Before answering this question, I'd like to give a brief explanation and value proposition of the framework and this particular component.

Why the heck do I want something like a WelcomeScreenStep?

The SAP BTP SDK for iOS accelerates your native mobile app development, for example, by providing reusable user interfaces and frameworks for common patterns like Onboarding.

Customers appreciate the SAPFioriFlows framework to model flows on how to onboard a new or existing end-user.

The SDK provides predefined onboarding steps to download settings from SAP Mobile Services, perform SAML or OAuth authentication, or create an encrypted data store.

One of those steps, the WelcomeScreenStep, allows you to easily configure and use a user interface with the purpose of

  • informing the user about how they can start the onboarding process
  • providing a way for the user to explore the app in demo mode or view features


The SAP Fiori for iOS implementation covers multiple variations of the welcome screen.

  • QR Code Scanner: The user must be provided a QR code to scan that is required to start the activation process. To read more, check out QR Code Scanner.

  • Mobile Device Management (MDM) and Hardcoded: You can leverage MDM to push configuration data down to the device. Or you, as a developer, can include the onboarding data into the compiled app. The app doesn't need a QR code scanner or other techniques to obtain the configuration information in both cases.
  • Activation Link: An activation link, generally provided in the welcome email, is required to start the activation process.

  • Discovery Service: The user is required to enter their corporate email address on this variation of the launch screen which the Discovery Service then uses to make the right backend connection.


Suppose you want to leverage a consistent Fiori experience, offer a demo mode, build an app store app for multiple customers, or allow end-users to connect against different SAP Mobile Services tenants. In that case, I recommend using the Welcome screen.

Don't use it If you have fundamentally different user interface requirements towards a Welcome screen or do not even want/need a Welcome screen.

What should I consider when not using the WelcomeScreenStep?

The WelcomeScreenStep is usually one of the first steps as it helps determine which SAP Mobile Services tenant the app shall connect to. Technically, the WelcomeScreenStep is responsible for setting important information in the OnboardingContext, and other predefined onboarding steps rely on such information in the OnboardingContext.

In particular:


You can implement and use a custom onboarding step that does not present a user interface but merely reads configuration information already present in your application and sets respective information in the OnboardingContext.

Here is a code snippet for a custom FileConfigurationProviderStep.


import SAPCommon
import SAPFoundation
import SAPFioriFlows

// Custom step as alternative to using SAPFioriFlows.WelcomeScreenStep
//  - reads configuration from `ConfigurationProvider.plist` and `AppParameters.plist`
//  - sets respective information into SAPFioriFlows.OnboardingContext
// IMPORTANT: app developer has to adjust implementation of computed property `transformer`
class FileConfigurationProviderStep: OnboardingStep {

    let logger = Logger.shared(named: "CustomOnboardingStep.LoadOnboardingConfigurationStep")

    var transformer: ConfigurationTransforming {
        // COPY-PASTE related code from generated OnboardingFlowProvider.swift, func `configureWelcomeScreenStep`
        let appParameters = FileConfigurationProvider("AppParameters").provideConfiguration().configuration
        let destinations = appParameters["Destinations"] as! NSDictionary
        return DiscoveryServiceConfigurationTransformer(applicationID: appParameters["Application Identifier"] as? String, authenticationPath: destinations["ESPMContainer"] as? String)

    init() {}

    func onboardOrRestore(context: SAPFioriFlows.OnboardingContext, completionHandler: @escaping (SAPFioriFlows.OnboardingResult) -> Void) {
        do {
            let configuration = FileConfigurationProvider().provideConfiguration().configuration as! [AnyHashable: Any]
            let config = try self.transformer.transform(config: configuration)
            logger.debug("Configuration successfully loaded from ConfigurationProvider.plist")
            var newContext = context
            config.forEach {[$0] = $1 }
        } catch {
            logger.error("", error: error)

    func onboard(context: SAPFioriFlows.OnboardingContext, completionHandler: @escaping (SAPFioriFlows.OnboardingResult) -> Void) {
        onboardOrRestore(context: context, completionHandler: completionHandler)

    func restore(context: SAPFioriFlows.OnboardingContext, completionHandler: @escaping (SAPFioriFlows.OnboardingResult) -> Void) {
        onboardOrRestore(context: context, completionHandler: completionHandler)

    func reset(context: SAPFioriFlows.OnboardingContext, completionHandler: @escaping () -> Void) {


You have to adjust the implementation of the computed transformer property !!

Assuming you have an Xcode project generated by the SAP BTP SDK Assistant for iOS, then change OnboardingFlowProvider.swift file to use the custom onboarding step instead of the predefined WelcomeScreenStep.


  public var onboardingSteps: [OnboardingStep] {
        return [
            FileConfigurationProviderStep(), //instead of configuredWelcomeScreenStep(),
            CompositeStep(steps: SAPcpmsDefaultSteps.configuration),
            // ...
    public var restoringSteps: [OnboardingStep] {
        return [
            FileConfigurationProviderStep(), // instead of configuredWelcomeScreenStep(),
            // ...


That's it 🙂