This section describes SAPFiori framework controls for implementing the Onboarding flows outlined in the Fiori Design Guidelines Onboarding patterns
FUIWelcomeScreen
UIViewController
is used to display a welcome/launch screen to the application for onboarding. The screen displays the application name, instructions on how to start the activation process, and an option to trigger the demo mode of the application. There are two versions of the launch screen. Version 1 does not have sign in. Version 2 has a sign in with an additional Activate
button for the activation process.
The application can conform to protocol OnboardingDelegate
to present the demo mode of the application by adopting with the didSelectDemoMode
function and to proceed to sign in by implementing the didSelectSignIn
function.
FUIWelcomeScreen
is implemented in FUIWelcomeScreen.storyboard. There are two ways to launch the screen:
- Use another storyboard and and use a
Present Modally
segue to theFUIWelcomeScreen
storyboard inSAPFiori
framework withcom.sap.cp.sdk.ios.SAPFiori
as Bundle.
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let vc = segue.destination as! FUIWelcomeScreen
vc.state = .isConfigured //shows version2 of the launch screen
//without calling vc.view.layoutSubviews(), components are not initialized. For example, vc.welcomeDetailLabel is still nil.
vc.view.layoutSubviews()
vc.detailLabel.text = "Thank you for downloading SAP Project Companion for Managers."
vc.delegate = self
}
- Load view controller programmatically:
let vc = FUIWelcomeScreen.createInstanceFromStoryboard()
vc.state = .isConfigured //shows version2 of the launch screen
vc.detailLabel.text = "Thank you for downloading SAP Project Companion for Managers."
self.navigationController?.pushViewController(vc, animated: true)
The
FUIWelcomeScreen
is supported for iPad portrait and landscape orientation and iPhone portrait orientation only. Since the screens are not supported in iPhone landscape orientation, the application installed on iPhone must switch to portrait mode before presenting these screens. The AppDelegate must lock the screen orientation when these screens display, as demonstrated in the following code snippet.
Usage
In app’s AppDelegate:
public var inFUIWelcomeScreen: Bool = false
// implement this function to support only portrait orientation when FUIWelcomeScreen is displayed.
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
if !inFUIWelcomeScreen {
return .allButUpsideDown
} else {
return .portrait
}
}
Before presenting FUIWelcomeScreen
:
// Let AppDelegate know that we are entering the screen
(UIApplication.shared.delegate as! AppDelegate).inFUIWelcomeScreen = true
// Make sure we rotate to portrait mode
let value = UIInterfaceOrientation.portrait.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
// Present the screen
let vc = FUIWelcomeScreen.createInstanceFromStoryboard()
vc.detailLabel.text = "Thank you for downloading SAP Project Companion for Managers."
self.navigationController?.pushViewController(vc, animated: true)
To dismiss the screen:
vc.dismiss(animated: true, completion: nil)
// Let AppDelegate know that we are exiting the view
(UIApplication.shared.delegate as! AppDelegate).inFUIWelcomeScreen = false
FUIPasscodeController
FUIPasscodeCreateController
, FUIPasscodeInputController
and FUIPasscodeChangeController
provide passcode and Touch ID screens with UI components for a typical modal window used for setting up a passcode and enabling iPhone native Touch ID for application authentication.
The strings used in FUIPasscodeSetupView, FUIPasscodeView, and FUITouchIDView are from localized Onboarding.strings file. The application can override these strings by setting the corresponding static variables in the FUIPasscodeController class at runtime.
Interface
FUIPasscodeCreateController
This UIViewController
is to be used by the app to set up the passcode and enable Touch ID screen flows.
FUIPasscodeInputController
This UIViewController
is to be used by the app to authenticate the user either by Touch ID or Passcode.
FUIPasscodeChangeController
This UINavigationController
is to be used by app to change the passcode.
Changing the passcode does not affect existing Touch ID preferences. There are no additional screens to display to enable touchID in the change passcode flow.
Usage
FUIPasscodeCreateController
Before the navigation controller presents this FUIPasscodeCreateController
, the following property
needs to be set:
delegate
: An implementation ofFUIPasscodeControllerDelegate
to handle events from this controller.
The application can also set this property for more passcode validation checks:
validationDelegate
: An implementation ofFUIPasscodeValidationDelegate
to validate the passcode user entered.
Here is the screen flow:
- The first screen prompts the user to enter the passcode.
After the user enters the passcode, which is validated with the
FUIPasscodePolicy
, theFUIPasscodeValidationDelegate
provided functionvalidate
ofvalidationDelegate
is invoked for additional validation. The next screen displays upon successful validation. - The second screen prompts the user to enter the passcode again to verify it against what was
entered in the first screen. The third screen displays when the passcodes match and touch ID is allowed in
FUIPasscodePolicy
. - The third screen prompts the user to enable or disable Touch ID authentication.
If the user chooses
Enable
, the passcode is saved as a Touch ID protected keychain item so that the passcode can be retrieved byFUIPasscodeInputController
later with Touch ID.
After the setup is complete, either with or without the third screen, the function shouldTryPasscode
of the FUIPasscodeControllerDelegate
is invoked. The delegate should either create a secure
store with the passcode, or save the passcode in a secure manner.
This passcode create flow is implemented in FUIPasscodeCreateController.storyboard
. There are two ways to invoke it:
- Use another storyboard and add a
Present Modally
segue to theFUIPasscodeCreateController
storyboard inSAPFiori
‘s framework bundlecom.sap.cp.sdk.ios.SAPFiori
. The application programmer needs to provide the properties needed inUIController
’s prepare for segue function:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destination = segue.destination as! UINavigationController
let vc0 = destination.viewControllers[0]
let vc = vc0 as! FUIPasscodeCreateController
vc.delegate = passcodeControllerDelegate
}
- Load it programmatically:
let storyboard = UIStoryboard(name: "FUIPasscodeCreateController", bundle: bundle)
let vc = storyboard.instantiateViewController(withIdentifier: "PasscodeCreateFirstViewController")
let passcodeVC = vc as! FUIPasscodeCreateController
// present the passcode view
let navController = UINavigationController(rootViewController: passcodeVC)
self.navigationController?.present(navController, animated: true, completion: nil)
FUIPasscodeInputController
Before the navigation controller presents this FUIPasscodeInputController
, the following properties
must be set up:
delegate
: An implementation ofFUIPasscodeControllerDelegate
to handle events from this controller.
This controller tries to determine if Touch ID is enabled by retrieving the value from the keychain. If Touch ID is enabled, a Touch ID authentication popup prompts the user to authenticate with Touch ID.
If Touch ID authentication succeeds, the saved passcode is retrieved and the function
shouldTryPasscode
of the FUIPasscodeControllerDelegate
implementation is invoked.
If Touch ID authentication is canceled or fails, the passcode view is shown to prompt the user to
enter a passcode. After entering the passcode, the function shouldTryPasscode
of the
FUIPasscodeControllerDelegate
implementation is invoked.
The delegate should dismiss this controller after the passcode is verified. isToShowCancelBarItem
is false
by default. When it is set to true
, the cancel button displays
on the navigation bar and can be used to dismiss the controller.
This passcode input flow is implemented in FUIPasscodeInputController.storyboard. There are two ways to invoke it:
- Use another storyboard and add a
Present Modally
segue to theFUIPasscodeInputController
storyboard in the SAPFiori framework bundle. The app programmer needs to provide the properties needed inUIController
’s prepare for segue function:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destination = segue.destination as! UINavigationController
let vc0 = destination.viewControllers[0]
let vc = vc0 as! FUIPasscodeInputController
vc.delegate = passcodeControllerDelegate
}
- Load it programmatically:
let storyboard = UIStoryboard(name: "FUIPasscodeInputController", bundle: bundle)
let vc = storyboard.instantiateViewController(withIdentifier: "PasscodeInputViewController")
let passcodeVC = vc as! FUIPasscodeInputController
// present the passcode view
let navController = UINavigationController(rootViewController: passcodeVC)
self.navigationController?.present(navController, animated: true, completion: nil)
FUIPasscodeChangeController
Set up the following properties before presenting this FUIPasscodeChangeController
:
- passcodeControllerDelegate: An implementation of
FUIPasscodeControllerDelegate
that handles events from this controller for bothFUIPasscodeInputController
andFUIPasscodeCreateController
. - validationDelegate: An implementation of
FUIPasscodeValidationDelegate
that validates the passcode entered by the user.
Here is the screen flow:
The first screen prompts the user to enter the current passcode using
FUIPasscodeInputController
. This controller always uses the passcode for authentication only.
Note: Even if touchID is enabled, the controller does not use touchID for authentication. After a passcode is entered, functionshouldTryPasscode
of theFUIPasscodeControllerDelegate
implementation is invoked. The application should not dismiss the controller in theshouldTryPasscode
implementation.The second screen prompts the user to enter a new passcode, which is validated by the
FUIPasscodePolicy
. TheFUIPasscodeControllerDelegate
provided functionvalidate
ofvalidationDelegate
is invoked for additional validation. Upon validation success, the next screen displays.The third screen prompts the user to enter the passcode again to verify the passcode entered in the second screen. After the setup is complete, the function
shouldTryPasscode
of theFUIPasscodeControllerDelegate
is invoked. The delegate should either create a secure store with the passcode, or save the passcode in a secure manner.
Note: Changing the passcode does not affect the existing Touch ID preferences. No additional screens display to enable touchID to change the passcode flow. If touchID was previously disabled before triggering the passcode change, touchID remains disabled. However, if touchID was previously enabled, the internal touchID-related data is automatically updated after the passcode is changed.
This passcode flow change is implemented in FUIPasscodeChangeController.storyboard
. There are two ways to invoke it:
- Use another storyboard and add a
Present Modally
segue to theFUIPasscodeChangeController
storyboard in theSAPFiori
framework bundle. The app developer must provide the required properties in theUIController
’s prepare for segue function:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let changeController = segue.destination as! FUIPasscodeChangeController
changeController.passcodeControllerDelegate = passcodeControllerDelegate
changeController.validationDelegate = validationDelegate
}
- Load it programmatically:
if let changeController = FUIPasscodeChangeController.createInstanceFromStoryboard() {
changeController.passcodeControllerDelegate = passcodeControllerDelegate
changeController.validationDelegate = validationDelegate
self.present(changeController, animated: true, completion: nil)
}
Both Passcode and Touch ID screens are supported for iPad portrait and landscape orientation and iPhone portrait orientation only. Since the screens are not supported in iPhone landscape orientation, the app installed on iPhone must switch to portrait mode before presenting these screens. The AppDelegate must lock the screen orientation when these screens display, as demonstrated in the following code snippet.
In app’s AppDelegate
:
public var inPasscodeView: Bool = false
// implement this function to support only portrait orientation when FUIPasscodeView is displayed.
func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask {
if !inPasscodeView {
return .allButUpsideDown
} else {
return .portrait
}
}
Before presenting the Passcode or Touch ID screen:
// Let AppDelegate know that we are entering FUIPasscodeView
(UIApplication.shared.delegate as! AppDelegate).inPasscodeView = true
// Make sure we rotate to portrait mode
let value = UIInterfaceOrientation.portrait.rawValue
UIDevice.current.setValue(value, forKey: "orientation")
// Present the passcode view
self.navigationController?.present(navController, animated: true, completion: nil)
After dismissing the Passcode or Touch ID screen:
passcodeController.dismiss(animated: true, completion: nil)
// Let AppDelegate know that we are exiting FUIPasscodeView
(UIApplication.shared.delegate as! AppDelegate).inPasscodeView = false