Skip to Content

Getting Started with the SAP Cloud Platform SDK for iOS

Part 2 — Registration using SAPFioriFlows

Previous (Setup)   Next (Logging)

A first step in an enterprise application is to have the app onboard or register against an app configuration defined in the SAP Cloud Platform Mobile Services. SAPFioriFlows provide an API to simplify this process which includes a welcome screen, a registration screen, an EULA screen, as well as app protection using a passcode, Touch ID or Face ID.

The following are some additional sources of documentation on SAPFioriFlows.
SAPFioriFlows API Reference
On-boarding Flow Recommendations
Authentication with Native iOS Mobile Interactive Tutorial

The following steps add the logic to onboard or register using basic authentication with the SAP Cloud Platform Mobile Services the first time the app starts. The second time the app starts, the saved credentials will be used so the user does not have to re-enter them.

    1. Right click on the parent folder of ViewController.swift (GettingStarted) and create a new file with the template Property List. Choose New File, then scroll down to the Resource section and select Property List. Name it ConfigurationProvider.plist and click Create.
    2. Right click on the ConfigurationProvider.plist file and choose Open As, Source Code.
      Place the below contents into the file and replace the XXXXXX value in host so it is correct for your SAP Cloud Platform Mobile Services server. The value can be seen on the APIs tab of the application.

      
      <?xml version="1.0" encoding="UTF-8"?>
      <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
      <plist version="1.0">
      <dict>
          <key>auth</key>
          <array>
              <dict>
                  <key>config</key>
                  <dict/>
                  <key>type</key>
                  <string>basic.default</string>
              </dict>
          </array>
          <key>host</key>
          <string>hcpms-XXXXXXtrial.hanatrial.ondemand.com</string>
          <key>protocol</key>
          <string>https</string>
          <key>appId</key>
          <string>com.iossdk.gs</string>
          <key>authPath</key>
          <string>com.sap.edm.sampleservice</string>
      </dict>
      </plist>
      
    3. Add the following import to the other imports at the top of ViewController.
      import SAPFioriFlows
      
    4. In ViewController add the following under the declaration for numberOfPresses.
      let presentationDelegate = ModalUIViewControllerPresenter()
      var myContext: OnboardingContext!
      var appId: String = ""
      var authPath: String = ""
      var serviceURL: URL = URL.init(string: "http://empty.org")!
      
      //Steps executed during Onboarding
      private var onboardingSteps: [OnboardingStep] {
      	return [
      		self.configuredWelcomeScreenStep(),
      		SAPcpmsSessionConfigurationStep(),
      		BasicAuthenticationStep(),
      		SAPcpmsSettingsDownloadStep(),
      		self.configuredStoreManagerStep(),
      	]
      }
      
      //Steps executed during Restoring
      private var restoringSteps: [OnboardingStep] {
      	return [
      		self.configuredStoreManagerStep(),
      		self.configuredWelcomeScreenStep(),
      		SAPcpmsSessionConfigurationStep(),
      		BasicAuthenticationStep(),
      		SAPcpmsSettingsDownloadStep(),
      	]
      }
    5. Add the following functions to ViewController.swift
      func configuredWelcomeScreenStep() -> WelcomeScreenStep {
      	let discoveryConfigurationTransformer = DiscoveryServiceConfigurationTransformer(applicationID: appId, authenticationPath: authPath)
      
      	//use the values from ConfigurationProvider.plist
      	let welcomeScreenStep = WelcomeScreenStep(transformer: discoveryConfigurationTransformer, providers: [FileConfigurationProvider()])   
      	
      	welcomeScreenStep.welcomeScreenCustomizationHandler = { welcomeScreen in
      		welcomeScreen.isDemoModeAvailable = false
      		welcomeScreen.headlineLabel.text = "Getting Started with the SAP Cloud Platform SDK for iOS"
      		welcomeScreen.detailLabel.text = "Use this app to explore the SAP Cloud Platform SDK for iOS"
      		welcomeScreen.primaryActionButton.titleLabel?.text = "Start"
      	}
      	return welcomeScreenStep
      }
      
      func configuredStoreManagerStep() -> StoreManagerStep {
      	let step = StoreManagerStep()
      	//Don’t use a local default passcode policy, but load passcode policy from server. If passcode policy is disabled on the server, the app won’t be protected with a passcode
      	//step.defaultPasscodePolicy = nil
      	return step
      }
      
      func onboardOrRestore() {
      	myContext = OnboardingContext(presentationDelegate: presentationDelegate)
      	
      	//If we previously onboarded
      	if let savedUUIDString = UserDefaults.standard.string(forKey: "userOnboardingID"), let uuid = UUID(uuidString: savedUUIDString) {
      		myContext.onboardingID = uuid
      		OnboardingFlowController.restore(on: restoringSteps, context: myContext) { result in
      			print("and the result is ...")
      			switch result {
      			case let .success(context):
      				print("Successfully restored")
      				self.myContext = context
      				//get host port from registration rather than hardcoded in plist with Discovery Service
      				//does not work when offline
      				//self.serviceURL = context.authenticationURL!
      			case let .failed(error):
      				print("Failed to restore: \(error)")
      				if (error.localizedDescription == "Passcode reset!") {
      					self.unregister()
      				}
      			}
      		}
      	}
      	//First time the app is opened so perform the onboarding flow
      	else {
      		OnboardingFlowController.onboard(on: onboardingSteps, context: myContext) { result in
      			print("and the result is ...")
      			switch result {
      			case let .success(context):
      				self.myContext = context
      				//get host port from registration rather than hardcoded in plist with Discovery Service
      				//does not work when offline
      				//self.serviceURL = context.authenticationURL!
      				UserDefaults.standard.set(context.onboardingID.uuidString, forKey:"userOnboardingID")
      				print("Successfully onboarded")
      			case let .failed(error):
      				print("Failed to onboard, retrying due to: \(error)")
      				URLCache.shared.removeAllCachedResponses()
      				HTTPCookieStorage.shared.removeCookies(since: Date.distantPast)
      				self.onboardOrRestore()
      			}
      		}
      	}
      }
      
      func unregister() {
      	OnboardingFlowController.reset(on: self.restoringSteps, context: myContext) {
      		URLCache.shared.removeAllCachedResponses()
      		HTTPCookieStorage.shared.removeCookies(since: Date.distantPast)
      		UserDefaults.standard.set(nil, forKey:"userOnboardingID")
      		self.onboardOrRestore()
      	}
      }
      
      func getAppConfig() {
      	var host = ""
      	if let path = Bundle.main.path(forResource: "ConfigurationProvider", ofType: "plist") {
      		let myDict = NSDictionary(contentsOfFile: path)
      		appId = myDict?.object(forKey: "appId") as! String
      		authPath = myDict?.object(forKey: "authPath") as! String
      		host = myDict?.object(forKey: "host") as! String
      	}
      	serviceURL = URL.init(string: "https://\(host)/\(authPath)")!
      }
      
    6. At the end of viewDidLoad function, start the onboarding process.
      getAppConfig()
      UINavigationBar.applyFioriStyle()
      onboardOrRestore()
    7. Run the app and the following screens are shown.Welcome Screen
      Note the LaunchScreen is shown first but it is an empty screen by default.

      Basic authentication screen

      Touch ID or Face ID screen
      Not Now was pressed. The Touch ID option can be enabled via the simulator’s Hardware, Touch ID or Face ID, Enrolled menu.

      Passcode screen
      This screen is shown if the device does not support Touch ID or Face ID or the Not Now button was pressed.

      By default, a Passcode Policy specifying that 8 characters must be entered is enforced.
      The Passcode Policy for the app can be managed by the Client Policy in the SAP Cloud Platform Mobile Services management cockpit for new registrations.
      Note, next time the app opens, just the passcode screen will be shown and the previously entered credentials will be used to fulfill any authentication challenges to the SAP Cloud Platform Mobile Services server.
      Note, if you app does not need a passcode screen, it can be disabled by unchecking the Enable Passcode Policy and uncommenting the below line in the method configuredStoreManagerStep.

      step.defaultPasscodePolicy = nil
      
    8. Notice that following a registration, the management cockpit will show the application’s registrations.
      Registrations that have not been used after a specified time can be automatically deleted. See the Automatic Removal section of the previous screen shot.
    9. This step is optional.
      In the above registration, the values for SAP Mobile Services server host and port are taken from the ConfigurationProvider.plist file that is part of the application. Another option to provide these values is the SAP Discovery Service or from a Mobile Device Management solution. See also Enabling Applications to Discover Configurations and App Configuration Using a Discovery Service Provider.  To try this out using the SAP Discovery Service follow the below steps.
      In the function configuredWelcomeScreenStep, replace FileConfigurationProvider with DiscoveryServiceConfigurationProvider and pass in the appId.

      //use values published in the discovery service.  
      let welcomeScreenStep = WelcomeScreenStep(transformer: discoveryConfigurationTransformer, providers: [DiscoveryServiceConfigurationProvider(applicationID: appId)])
      

      To publish the configuration, click Publish to Discovery Service.


      Notice below that the supplied domain of the email address must match one of the configured domains in the SAP Discovery Service.

    10. Note, that a JSON string containing the published configuration can be seen by making a request in the browser as shown below.

      https://discovery.sapmobilesecure.com/config-api.svc/ApplicationConfigurations/getApplicationConfiguration(AppConfigID='com.iossdk.gs:1.0',EmailAddress='dan@trial-pXXXXXXXtrial.sapmobileplace.com')

Previous (Setup)   Next (Logging)

To report this post you need to login first.

Be the first to leave a comment

You must be Logged on to comment or reply to a post.

Leave a Reply