Onboarding patterns
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
-
This
UIViewController
is base controller class to display a welcome/launch screen to the application for onboarding. *Declaration
Swift
open class FUIWelcomeController : UIViewController
-
This
UIViewController
is used to display a welcome/launch screen to the application for onboarding. The screen mainly displays the application name, instructions on how to start the activation process and an option to trigger the demo mode of the application.Application can implement the
FUIWelcomeControllerDelegate
protocol, to present the demo mode of the application by adopting with thedidSelectDemoMode(_:)
function, to proceed sign in by implementing theshouldContinueUserOnboarding(_:)
function, to proceed configuration based on the configuration options by implementing thewelcomeController(_:willNavigateToActivationScreen:)
,welcomeController(_:shouldTryUserEmail:)
, orwelcomeController(_:willNavigateToScannerScreen:)
functions.FUIWelcomeScreen
is implemented inFUIWelcomeScreen.storyboard
. There are two ways to launch the screen:- Use another story board and use a
Present Modally
segue toFUIWelcomeScreen
storyboard inSAPFiori
framework withcom.sap.cp.sdk.ios.SAPFiori
as Bundle. App programmer needs to provide the properties needed inUIController
‘s prepare for segue function:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) { let vc = segue.destination as! FUIWelcomeScreen vc.state = .isConfigured vc.detailLabel.text = "Thank you for downloading SAP Project Companion for Managers." vc.delegate = self }
- Programmatically loads it:
let vc = FUIWelcomeScreen.createInstanceFromStoryboard() vc.state = .isConfigured vc.detailLabel.text = "Thank you for downloading SAP Project Companion for Managers." self.navigationController?.pushViewController(vc, animated: true)
Settings for possible welcome screens being launched:
Launch with Standard: Application contains the necessary configurations to connect to mobile services, and should prompt user to Start.
state
property:.isConfigured
configurationOptions
property: not required. Value would be ignored.delegate
function(s) to be implemented:shouldContinueUserOnboarding(_:)
,didSelectDemoMode(_:)
ifisDemoAvailable
istrue
.
Welcome Screen Launched with Link: Application has not been configured, and does not use
FUIWelcomeScreen
flow to obtain configuration.state
property:.notConfigured
configurationOptions
property: empty valuedelegate
function(s) to be implemented:didSelectDemoMode(_:)
ifisDemoAvailable
istrue
Welcome Screen Launched with Discovery Service: Application has not been configured, and should prompt the end user for their email address.
state
property:.notConfigured
configurationOptions
property: .discoveryServicedelegate
function(s) to be implemented:welcomeController(_:shouldTryUserEmail:)
,didSelectDemoMode(_:)
ifisDemoAvailable
istrue
Welcome Screen Launched with Scanner: Application has not been configured, and should prompt the end user to launch the Barcode Scanner to obtain connection settings.
state
property:.notConfigured
configurationOptions
property: .barcodeScannerdelegate
function(s) to be implemented:welcomeController(_:willNavigateToScannerScreen:)
,didSelectDemoMode(_:)
ifisDemoAvailable
istrue
Welcome Screen Launched with Activation: Application has not been configured, and should prompt the end user to pick between email address entry, or the Barcode Scanner, to obtain connection settings.
state
property:.notConfigured
configurationOptions
property: [.discoveryService, .barcodeScanner]delegate
function(s) to be implemented:welcomeController(_:willNavigateToActivationScreen:)
,didSelectDemoMode(_:)
ifisDemoAvailable
istrue
Note that the FUIWelcomeScreen is supported for iPad portrait and landscape orientation and iPhone portrait orientation only. Since the screen is not supported in iPhone landscape orientation, the app needs to switch to portrait mode before presenting the screen. And AppDelegate needs to lock the screen orientation when these screens are shown, similar to the following code snippet.
In app’s AppDelegate:
public var inFUIWelcomeScreen: Bool = false // implement this function to support only portrait orientation when FUIWelcomeScreen is displayed in iPhone. func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { if !inFUIWelcomeScreen { return .allButUpsideDown } else { return .portrait } }
Before presenting the
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)
After dismissing the Passcode or Touch ID screen:
onboardingScreen.dismiss(animated: true, completion: nil) // Let AppDelegate know that we are exiting the view (UIApplication.shared.delegate as! AppDelegate).inFUIWelcomeScreen = false
## Theming Supported style classes
fdlFUIWelcomeScreen fdlFUIWelcomeScreen_headlineLabel fdlFUIWelcomeScreen_detailLabel fdlFUIWelcomeScreen_emailTextField fdlFUIWelcomeScreen_primaryActionButton fdlFUIWelcomeScreen_footnoteLabel fdlFUIWelcomeScreen_footnoteActionButton fdlFUIWelcomeScreen_logoImageView
## Attention
The delegate object with type
See moreFUIWelcomeControllerDelegate
is declared as a weak reference. So on deallocation it will be automatically set to nil. To keep it alive as expected, developer should retain the delegate object during its whole execution scope.Declaration
Swift
open class FUIWelcomeScreen : FUIWelcomeController, UITextFieldDelegate
- Use another story board and use a
-
This protocol provides method for handling button actions on a FUIWelcomeScreen view.
See moreDeclaration
Swift
@objc public protocol FUIWelcomeControllerDelegate : AnyObject
-
Describes different onboarding states in onboarding process flow.
See moreDeclaration
Swift
public enum FUIWelcomeControllerState : Int
-
Describes different onboarding configuration options in onboarding process flow.
Note
Note The property would be ignored if
state
isisConfigured
Note
Note The property should be set to
[.discoveryService, .barcodeScanner]
for the following user case: When application has not been configured, and should prompt the end user to pick between email address entry, or the Barcode Scanner, to obtain connection settings.Declaration
Swift
public struct FUIWelcomeControllerConfigurationOption : OptionSet
-
This protocol provides method for handling button actions on a FUIWelcomeScreen view.
See moreDeclaration
Swift
@objc public protocol FUIOnboardingDelegate : AnyObject
-
Undocumented
Declaration
Swift
public typealias FUIOnboardingState = FUIWelcomeControllerState
-
The Activation Screen is presented after the Welcome Screen in the case of an onboarding scenario where the application has not been configured, and should prompt the end user to pick between email address entry or the barcode scanner, to obtain connection settings. The screen displays a headline Label with the title and a detailLabel with instructions on how to start the activation process and options to enter the email address or click the Scan button to proceed to the next step in the onboarding process.
Theming
Supported style classes
fdlFUIActivationScreen fdlFUIActivationScreen_headlineLabel fdlFUIActivationScreen_detailLabel fdlFUIActivationScreen_primaryActionButton fdlFUIActivationScreen.subheadlineLabel fdlFUIActivationScreen_secondaryActionButton
Attention
The delegate object with type
See moreFUIWelcomeControllerDelegate
is declared as a weak reference. So on deallocation it will be automatically set to nil. To keep it alive as expected, developer should retain the delegate object during its whole execution scope.Declaration
Swift
open class FUIActivationScreen : FUIWelcomeController, UITextFieldDelegate
-
This controller is to display the scanner view to scan a QR code for app activation. It is also displaying the image thumbnails from camera roll and a button to start photo picker that user may choose the QR code image directly.
Theming
Supported style classes
fdlFUIOnboardingScanViewController fdlFUIOnboardingScanViewController_cancelButton fdlFUIOnboardingScanViewController_flashButton fdlFUIOnboardingScanViewController_choosePhotoButton fdlFUIOnboardingScanViewController_arrowButton fdlFUIOnboardingScanViewController_scanGuidesImageView fdlFUIOnboardingScanViewController_photoPicker_navigationBar
Attention
The delegate object with type
See moreFUIOnboardingScanViewControllerDelegate
is declared as a weak reference. So on deallocation it will be automatically set to nil. To keep it alive as expected, developer should retain the delegate object during its whole execution scope.Declaration
Swift
public class FUIOnboardingScanViewController : UIViewController, FUIBarcodeScannerDelegate, UICollectionViewDataSource, UICollectionViewDelegate
-
Delegate protocol for
See moreFUIOnboardingScanViewController
.Declaration
Swift
@objc public protocol FUIOnboardingScanViewControllerDelegate : AnyObject
-
This is the view that will be displayed when the scanner got a QR code from either scanner or a photo image. And this QR code is validated by the delegate of the
FUIOnboardingScanViewController
.This view includes the following components:
- Title label: with default text
Confirmation
- Check image: a green circle with white check mark in the middle
- Success message label: with default text
Scan succeeded. You will be connected to:
HCP server label: the text should be the hcp server name that the implementation of the following function of
FUIWelcomeControllerDelegate
should provide.func welcomeController(_ welcomeController: FUIWelcomeController, willNavigateToScannerScreen scanController: FUIOnboardingScanViewController)
Continue button: when this is tapped, the app will continue rest of the orboarding tasks.
Theming
Supported style classes
See morefdlFUIOnboardingScanConfirmView fdlFUIOnboardingScanConfirmView_titleLabel fdlFUIOnboardingScanConfirmView_successMessageLabel fdlFUIOnboardingScanConfirmView_hcpServerLabel fdlFUIOnboardingScanConfirmView_continueButton fdlFUIOnboardingScanConfirmView_continueButton_touchDown
Declaration
Swift
open class FUIOnboardingScanConfirmView : NibDesignable
- Title label: with default text
-
This
UIViewController
is to be used by app to setup the passcode and enabling Touch ID screen flows.Before the navigation controller presents this
FUIPasscodeCreateController
, the following property needs to be set:- delegate: An implementation of
FUIPasscodeControllerDelegate
to hanle events from this controller.
Application can also set this property for more passcode validation checks:
- validationDelegate: An implementation of
FUIPasscodeValidationDelegate
to validate the passcode user entered.
Here is the screen flow:
The first screen is the Touch ID or Face ID screen, depends on the device capability, which prompts user to decide if enable Touch ID/Face ID authentication or not.
When there are fingerprints or Face ID enrolled, there will be one
Enable
button only. When user tapped this button, a passcode is generated and saved in a biometric ID protected keychain item. TheshouldTryPasscode
function of the delegate will be invoked with the generated passcode. User will then need to use Touch ID or Face ID in theFUIPasscodeInputController
for the login flow.When there is no fingerprints or Face ID enrolled, there will be one
Not Now
button, in addition to theEnable
button. WhenNot Now
is tapped, the second screen is shown to let user enter passcode. IfEnable
is tapped, in this case, an alert pop-up screen will be shown with two options,Not Now
orSettings
. TappingNot Now
will dismiss the pop-up alert, while tappingSettings
will open the Settings app to let user enroll fingerprints or Face ID.The second screen prompts user to enter passcode. After user entered the passcode which is validated with the
FUIPasscodePolicy
. TheFUIPasscodeValidationDelegate
provided functionvalidate
ofvalidationDelegate
is invoked for additional validation. If validation success, the next screen will be displayed; otherwise, the function throwsFUIPasscodeControllerError
when validation fails.The third screen prompts user to enter passcode again to verify with the passcode entered in the first screen. The function
shouldTryPasscode
of theFUIPasscodeControllerDelegate
is invoked when passcode is verified.
When 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.This passcode create flow is implemented in
FUIPasscodeCreateController.storyboard
. There are two ways to invoke it:- Use another story board and using a
Present Modally
segue toFUIPasscodeCreateController
storyboard inSAPFiori
‘s framework bundlecom.sap.cp.sdk.ios.SAPFiori
. 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! FUIPasscodeCreateController //assigning a `FUIPasscodeControllerDelegate` delegate is a must vc.delegate = passcodeControllerDelegate }
- Programmatically loads it:
let passcodeVC = FUIPasscodeCreateController.createInstanceFromStoryboard() //assigning a `FUIPasscodeControllerDelegate` delegate is a must passcodeVC.delegate = passcodeControllerDelegate // present the passcode view let navController = UINavigationController(rootViewController: passcodeVC) self.navigationController?.present(navController, animated: true, completion: nil)
## Theming Supported style classes
See morefdlFUIPasscodeCreateController fdlFUIPasscodeCreateController_navigationController_navigationBar fdlFUIPasscodeCreateController_cancelItem fdlFUIPasscodeCreateController_nextItem fdlFUIPasscodeCreateController_doneItem fdlFUIPasscodeCreateController_changeMode_cancelItem fdlFUIPasscodeCreateController_changeMode_nextItem fdlFUIPasscodeCreateController_changeMode_doneItem
Declaration
Swift
public class FUIPasscodeCreateController : FUIPasscodeController, FUIPasscodeViewDelegate, FUITouchIDViewDelegate
- delegate: An implementation of
-
This delegate is responsible to do additional validations to the passcode user entered.
See moreFUIPasscodeCreateController
will validate the passcode user entered with theFUIPasscodePolicy
internally.Declaration
Swift
public protocol FUIPasscodeValidationDelegate : AnyObject
-
This
UIViewController
is to be used by app to authenticate user by either Touch ID or Passcode.Before the navigation controller presents this
FUIPasscodeInputController
, the following properties needs to be setup:- delegate: An implementation of
FUIPasscodeControllerDelegate
to handle events from this controller. - hashUserPasscode: This boolean property needs to be the same as the same property in
FUIPasscodeCreateController
that was used to setup the passcode. - userIdentifier: This String property also needs to be the same as the same property in
FUIPasscodeCreateController
that was used to setup the passcode.
This controller will try to determine if Touch ID is enabled by retrieving the value from keychain. If Touch ID is enabled, there will be Touch ID authentication popup to prompt user authenticate with Touch ID.
If Touch ID authentication succeeded, the saved passcode will be retrieved and function
shouldTryPasscode
of theFUIPasscodeControllerDelegate
implementation will be invoked.If Touch ID authentication is canceled or failed, the passcode view will be shown to prompt user enter passcode. After user entered the passcode, function
shouldTryPasscode
of theFUIPasscodeControllerDelegate
implementation will be invoked.The delegate should dismiss this controller after the passcode is verified.
This passcode input flow is implemented in
FUIPasscodeInputController.storyboard
. There are two ways to invoke it:- Use another story board and using a
Present Modally
segue toFUIPasscodeInputController
storyboard inSAPFioriUI
framework bundle. 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 }
- Programmatically loads it:
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)
## Theming Supported style classes
See morefdlFUIPasscodeInputController fdlFUIPasscodeInputController_doneItem fdlFUIPasscodeInputController_cancelItem
Declaration
Swift
public class FUIPasscodeInputController : FUIPasscodeController, FUIPasscodeViewDelegate
- delegate: An implementation of
-
Use this
UINavigationController
to change the passcode screen flows in the application.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.
Note that the properties
hashUserPasscode
anduserIdentifier
need to be the same as theFUIPasscodeCreateController
in order for the change to be successful.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: If Touch ID is enabled, there will be Touch ID authentication popup to prompt user authenticate with Touch ID. Once user enters fingerprint or device passcode, the stored passcode in the keychain is retrieved and the delegat’sshouldTryPasscode
is invoked to validate the old passcode. And a new passcode is generated andshouldTryPasscode
is invoked again to validate the new passcode. The new passcode is then saved in the keychain without other user actions.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 }
- Programmatically load it:
See morelet changeController = FUIPasscodeChangeController.createInstanceFromStoryboard() changeController.passcodeControllerDelegate = passcodeControllerDelegate changeController.validationDelegate = validationDelegate self.present(changeController, animated: true, completion: nil)
Declaration
Swift
public class FUIPasscodeChangeController : UINavigationController
- passcodeControllerDelegate: An implementation of
-
This is the base class of
FUIPasscodeCreateController
andFUIPasscodeInputController
. It has the common codes for those two view controllers.Note that both Passcode screen and Touch ID screen 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 in iPhone needs to switch to portrait mode before presenting these screens. And AppDelegate needs to lock the screen orientation when these screens are shown, similar to the following code snippet.
In app’s AppDelegate:
public var inPasscodeView: Bool = false // implement this function to support only portrait orientation when FUPasscodeView is displayed in iPhone. 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
The strings used in
FUIPasscodeSetupView
,FUIPasscodeView
, andFUITouchIDView
are from localized Onboarding.strings file. Application can override these strings by setting the corresponding static variables in this FUIPasscodeController class at runtime.## Theming Supported style classes
fdlFUIPasscodeController fdlFUIPasscodeController_navigationController_navigationBar
## Attention
The delegate object with type
See moreFUIPasscodeControllerDelegate
is declared as a weak reference. So on deallocation it will be automatically set to nil. To keep it alive as expected, developer should retain the delegate object during its whole execution scope.Declaration
Swift
open class FUIPasscodeController : UIViewController, FUIPrivateEncryptionKeyGenerator
-
This protocol defines the functions needed for
See moreFUIPasscodeController
to notify the app about passcode and TouchID events.Declaration
Swift
public protocol FUIPasscodeControllerDelegate : AnyObject
-
This error is to be thrown by
See moreFUIPasscodeControllerDelegate
implementation when functionshouldTryPasscode
is called with a passcode that failed to open the secure store or match the saved passcode.Declaration
Swift
public enum FUIPasscodeControllerError : Error
-
Protocol to allow to create a private encryption key
See moreDeclaration
Swift
public protocol FUIPrivateEncryptionKeyGenerator : AnyObject
-
Passcode input mode. Typically used in
See moreshouldTryPasscode
function as one of the arguments to indicate the current mode. When theshouldTryPasscode
function is triggered byFUIPasscodeInputController
, the mode can be eithermatch
ormatchForChange
. when the function is triggered byFUIPasscodeCreateController
, the mode is eithercreate
orchange
.Declaration
Swift
public enum FUIPasscodeInputMode : Int
-
The passcode policy structure.
See moreDeclaration
Swift
public struct FUIPasscodePolicy
-
The passcode rule structure used to add a user defined passcode rule to the passcode policy.
See moreDeclaration
Swift
public struct FUIPasscodeRule
-
This is a ‘UIViewController’ to display the error view when Touch ID or Face ID authentication is cancelled.
Developer could set the static string properties in this class to override the default text displayed in this view.
Theming
See morefdlFUITouchIDErrorViewController_errorTitleLabel { font-color: @primary1; } fdlFUITouchIDErrorViewController_errorMessageLabel { font-color: @primary1; } fdlFUITouchIDErrorViewController_actionButton { font-size: 16; font-name: system; font-color: @primary6; background-color: @tintColorDark; corner-radius: 8; border-width: 1; border-color: @tintColorDark; /* order (with whitespace as separator): [top] [right] [bottom] [left]
Declaration
Swift
public class FUITouchIDErrorViewController : UIViewController
-
This
FUIBasicAuthenticationScreen
is anUIViewController
to display the screen to prompt user to enter username and password to do basic authentication.It has a headline label and a detail lable to display the title and a detail message for this screen. There are two input fields for user input username and password. And one primary action button. The button will be enabled when both the username and password are not empty.
There is also a cancel button on the navigation bar for user to cancel the basic authentication process.
Developer should implement
FUIBasicAuthenticationDelegate
and set it to thedelegate
property to handle user responses.func presentDynamicAuthenticationScreen() { let controllers = FUIBasicAuthenticationScreen.createInstanceFromStoryboard() let basicAuthController = controllers.basicAuthenticationScreen basicAuthController.loadViewIfNeeded() basicAuthController.delegate = self self.navigationController?.present(controllers.navigationController, animated: true, completion: nil) } func didSignIn(_ controller: FUIBasicAuthenticationScreen, username: String, password: String, completion: @escaping ((_ errorMessage: String?) -> Void)) { var signInErrorMessage: String? = nil // Send username and password to server for verification here // Simulate callback from verification process DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) { // This is for testing purposes only. if !self.signInOk || username == password { signInErrorMessage = "Sign In Failed" } completion(signInErrorMessage) if signInErrorMessage == nil { controller.dismiss(animated: true, completion: nil) } } } func didCancel(_ controller: FUIBasicAuthenticationScreen) { print("User Cancelled Basic Authentication") controller.dismiss(animated: true, completion: nil) }
Theming
See morefdlFUIBasicAuthenticationScreen_headlineLabel { font-size: 28; font-name: thinSystem; font-color: @primary1; } fdlFUIBasicAuthenticationScreen_detailLabel { font-style: body; font-color: @primary1; } fdlFUIBasicAuthenticationScreen_primaryActionButton { font-style: callout; font-color: @primary6; corner-radius: 8; background-color-normal: @tintColorDark; background-color-highlighted: @backgroundGradientTop; background-color-disabled: @line; font-color-disabled: #28666666; /*primary2 with 0.4 alpha; "28" is the hex value of 20% for alpha; "666666" is primary2
Declaration
Swift
open class FUIBasicAuthenticationScreen : FUIWelcomeController
-
The delegate protocol for the basic authentication screen.
See moreDeclaration
Swift
public protocol FUIBasicAuthenticationDelegate : AnyObject
-
The
FUIDynamicAuthenticationScreen
is anUIViewController
to display the screen to prompt user to enter information needed for authentication.It has a message lable and a number of the input fields for user to enter information needed. The input fields are configured using the
informationFields
property.There is a ‘Cancel’ button on the navigation bar for user to cancel the authentication process. There is also a ‘Done’ button on the navigation bar for user to submit the information. The
Done
button is disabled until all the input fields are not empty.Developer should implement
FUIDynamicAuthenticationDelegate
and set it to thedelegate
property to handle user responses.var dynamicAuthenticationScreen: FUIDynamicAuthenticationScreen? var completionBlock: ((_ errorMessage: String?) -> Void)? func presentDynamicAuthenticationScreen() { let controllers = FUIDynamicAuthenticationScreen.createInstanceFromStoryboard() let dynamicAuthController = controllers.dynamicAuthenticationScreen dynamicAuthController.informationFields = [ FUIAuthenticationInformationField(placeholder: "username", isSecureText: false, informationString: "Admin"), FUIAuthenticationInformationField(placeholder: "password", isSecureText: true, informationString: nil), FUIAuthenticationInformationField(placeholder: "url", isSecureText: false, informationString: nil), FUIAuthenticationInformationField(placeholder: "test field", isSecureText: false, informationString: nil) ] dynamicAuthController.delegate = self self.navigationController?.present(controllers.navigationController, animated: true, completion: nil) } func verify(_ controller: FUIDynamicAuthenticationScreen, informationStrings: [String], completion: @escaping ((_ errorMessage: String?) -> Void)) { dynamicAuthenticationScreen = controller completionBlock = completion // Send information to server for verification here // Simulate callback from verification process DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) { self.verificationDone() } } func verificationDone() { completionBlock?(verificationErrorMessage) if verificationErrorMessage == nil { dynamicAuthenticationScreen?.dismiss(animated: true, completion: nil) } } func didCancel(_ controller: FUIBasicAuthenticationScreen) { print("User Cancelled Basic Authentication") controller.dismiss(animated: true, completion: nil) }
Theming
fdlFUIDynamicAuthenticationScreen_detailLabel { font-color: @primary1; } fdlFUIDynamicAuthenticationScreen_cancelButton { background-tint-color: @tintColorDark; } fdlFUIDynamicAuthenticationScreen_doneButton { background-tint-color: @tintColorDark; } fdlFUIDynamicAuthenticationScreen_messageBannerTitleLabel { font-color: @primary7; } fdlFUIDynamicAuthenticationScreen_messageBannerDividerTop { background-color: @line; } fdlFUIDynamicAuthenticationScreen_errorMessageBannerTitleLabel { font-color: @negative; } fdlFUIDynamicAuthenticationScreen_errorMessageBannerDividerTop { background-color: @negative; }
Attention
The delegate object with type
See moreFUIDynamicAuthenticationDelegate
is declared as a weak reference. So on deallocation it will be automatically set to nil. To keep it alive as expected, developer should retain the delegate object during its whole execution scope.Declaration
Swift
open class FUIDynamicAuthenticationScreen : FUIWelcomeController
-
The delegate protocol for the authentication screen.
See moreDeclaration
Swift
public protocol FUIDynamicAuthenticationDelegate : AnyObject
-
This
UIViewController
is used to display the End User License Agreement, EULA. There are 2 buttons on the tool bar at the bottom of the screen,Agree
andDisagree
, to let choose to confirm or reject the agreement. In addition, there is aCancel
button at the left on the navigation bar.Developer should provide the text for the
headlineLabel
property, the attributed text for theeulaTextView
property, and set the delegate property to handle user interactions.let eulaController = FUIEULAViewController.createInstanceFromStoryboard() eulaController.headlineLabel.text = "CUSTOM EULA" eulaController.eulaTextView.attributedText = NSAttributedString(string: "This is a legally binding agreement (\"Agreement\") between ...", attributes: [NSAttributedStringKey.font: UIFont(name: "Georgia", size: 24.0)! ]) eulaController.delegate = self let navController = UINavigationController.init(rootViewController: eulaController) self.navigationController?.present(navController, animated: true, completion: nil)
Theming
fdlFUIEULAView_headlineLabel { font-size: 28; font-name: thinSystem; font-color: @primary1; } fdlFUIEULAView_confirmButton { background-tint-color: @tintColorDark; } fdlFUIEULAView_rejectButton { background-tint-color: @tintColorDark; } fdlFUIEULAView_cancelButton { background-tint-color: @tintColorDark; }
Attention
The delegate object with type
See moreFUIEULADelegate
is declared as a weak reference. So on deallocation it will be automatically set to nil. To keep it alive as expected, developer should retain the delegate object during its whole execution scope.Declaration
Swift
open class FUIEULAViewController : FUIWelcomeController
-
Undocumented
See moreDeclaration
Swift
public protocol FUIEULADelegate : AnyObject
-
Multifunctional view for displaying Information or Splash screen. The UI elements can be hidden or showed depending on functionality. The text properties must be set before displaying the view.
Theming
Example nss definitions
See morefdlFUIInfoViewScreen_titleTextView { font-color: @primary1; placeholder-color: green; } fdlFUIInfoViewScreen_informationTextView { font-color: @primary1; placeholder-color: green; } fdlFUIInfoViewScreen_primaryButton { font-color: @primary1; } fdlFUIInfoViewScreen_secondaryButton { font-color: @primary1; }
Declaration
Swift
open class FUIInfoViewController : UIViewController
-
Undocumented
See moreDeclaration
Swift
public protocol FUIInfoViewControllerDelegate : AnyObject
-
Protocol implemented by FUISinglePageUserConsentForm and FUIMultiPageUserConsentForm
See moreDeclaration
Swift
public protocol FUIUserConsentForm
-
FUIUserConsentPage() represents a single page in a user consent form. An FUISinglePageUserConsentForm only contains one instance of the FUIUserConsentPage(). An FUIMultiPageUserConsentForm can contain many FUIUserConsentPage() instances which constitute the multiple pages of the form.
See morelet page1 = FUIUserConsentPage() page1.title.text = "Data Privacy" page1.body.text = "Detailed text about how data privacy pertains to this app and why it is important for the user to enable this functionality" page1.actionTitle.text = "Learn more about Data Privacy" page1.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 userconsentpages = [page1] let multipageform = FUIMultiPageUserConsentForm(pages: userconsentpages)
Declaration
Swift
open class FUIUserConsentPage : FUIUserConsentPageComponent
-
This
UIViewController
is used to display a series of user consent screens modally during the process of onboarding. The propertyforms
must be supplied, which is an array of objects of the two classes that conform to the FUIUserConsentForm protocol, namely FUISinglePageUserConsentForm and FUIMultiPageUserConsentForm. The Fiori for iOS SDK takes these forms and displays them modally as single or multipage user consent screens using the FUIUserConsentViewController. A user consent screen contains a title , a brief information on the topic for which the user consent is required and a link to more details. There are 2 buttons in the toolbar,Agree
andDisagree
, if the consent form is mandatory orAgree
andNot Now
, if the consent form is optional. In the case of a mandatory form, the user can proceed to the next step of onboarding only when they agree to the terms stated in the form. In the case of an optional form, the user can choose to click theNot Now
button and proceed with the onboarding. In addition, there is aCancel
button in the navigation bar. The toolbar buttons and the cancel button invoke theFUIUserConsentViewControllerDelegate
methods which can be used to handle the application logic based on the user input. If the form is a multi page consent form, only the last page in the form displays the toolbar and cancel buttons. Each consent form has thetitle
poperty,body
containing the details, anactionTitle
,which when clicked invokes theactionHandler
. There are also thetitleAttributedText
,bodyAttributedText
andactionTitleAttributedText
properties , which when supplied take precedence over the title, body and actionTitle properties. Eg. When bothtitle
andtitleAttributedText
are supplied, onlytitleAttributedText
is displayed.let spForm = createSinglePageForm() spForm.isRequired = false let mpForm = createMultiPageForm() mpForm.isRequired = false let forms = [spForm,mpForm] as [Any] (UIApplication.shared.delegate as! AppDelegate).inUserConsentScreen = true let ctrller = FUIUserConsentViewController() ctrller.delegate = self ctrller.forms = forms as! [FUIUserConsentForm] self.navigationController?.present(ctrller, animated: true, completion: nil) func createSinglePageForm()->FUISinglePageUserConsentForm { let singlepageform = FUISinglePageUserConsentForm() singlepageform.title.text = "Data Privacy" singlepageform.body.text = "Detailed text about how data privacy pertains to this app and why it is important for the user to enable this functionality" singlepageform.actionTitle.text = "Learn more about Data Privacy" singlepageform.actionHandler = { controller in let alert = UIAlertController(title: "Want Data Privacy?", message: "Be wise about your data", preferredStyle: UIAlertControllerStyle.alert) alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil)) controller.present(alert, animated: true, completion: nil) } return singlepageform } func createMultiPageForm()->FUIMultiPageUserConsentForm { let page1 = FUIUserConsentPage() page1.title.text = "Data Privacy" page1.body.text = "Detailed text about how data privacy pertains to this app and why it is important for the user to enable this functionality" page1.actionTitle.text = "Learn more about Data Privacy" page1.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 page2 = FUIUserConsentPage() page2.title.text = "Security" page2.body.text = "Detailed text about how data privacy pertains to this app and why it is important for the user to enable this functionality. " page2.actionTitle.text = "Learn more about Data Privacy" page2.actionHandler = { controller in let alert = UIAlertController(title: "Security", message: "Alert for data security page", preferredStyle: UIAlertControllerStyle.alert) alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil)) controller.present(alert, animated: true, completion: nil) } let page3 = FUIUserConsentPage() page3.title.text = "Consent" page3.body.text = "Detailed text about how data privacy pertains to this app and why it is important for the user to enable this functionality" page3.actionTitle.text = "Learn more about Data Privacy" page3.actionHandler = { controller in let alert = UIAlertController(title: "Consent", message: "Alert for consent page", preferredStyle: UIAlertControllerStyle.alert) alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil)) controller.present(alert, animated: true, completion: nil) } let userconsentpages = [page1,page2,page3] let multipageform = FUIMultiPageUserConsentForm(pages: userconsentpages) return multipageform }
Application should also implement the
FUIUserConsentViewControllerDelegate
protocol, which provides the delegate methods that handle the application flow based on whether the user agrees, disagrees or cancels the form. It is important that the FUIUserConsentViewController , passed in as the parameterviewController
must be dismissed first as shown below, before proceeding with any other application logic based on the user response to the forms.func userConsentViewController( viewController: FUIUserConsentViewController, didCancelConsentForms forms: [FUIUserConsentForm]) { viewController.dismiss(animated: true, completion: nil) let alert = UIAlertController(title: "Cancelled", message: "User cancelled Onboarding", preferredStyle: UIAlertControllerStyle.alert) (UIApplication.shared.delegate as! AppDelegate).inUserConsentScreen = false alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil)) self.present(alert, animated: true, completion: nil) } func userConsentViewController( viewController: FUIUserConsentViewController, didReceiveResponseToConsentForms forms: [FUIUserConsentForm]) { (UIApplication.shared.delegate as! AppDelegate).inUserConsentScreen = false var NumAccepted = 0 for form in forms { if (form.isUserAccepted) { NumAccepted = NumAccepted + 1 } } viewController.dismiss(animated: true, completion: nil) if (NumAccepted > 0) { let alert = UIAlertController(title: "Status", message: "User accepted \(NumAccepted) form(s)", preferredStyle: UIAlertControllerStyle.alert) alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil)) self.present(alert, animated: true, completion: nil) } }
Note that the user consent screen orientations are supported for iPad portrait and landscape orientation and iPhone portrait orientation only.Since the screen is not supported in iPhone landscape orientation,the app needs to switch to portrait mode before presenting the screen and the AppDelegate needs to lock the screen orientation when these screens are shown, similar to the following code snippet.
In app’s AppDelegate:
public var inUserConsentScreen: Bool = false // Implement this function to support only portrait orientation when FUIUserConsentScreen is displayed in iPhone. func application(_ application: UIApplication, supportedInterfaceOrientationsFor window: UIWindow?) -> UIInterfaceOrientationMask { if !inUserConsentScreen { return .allButUpsideDown } else { return .portrait } }
Before presenting the
FUIUserConsentViewController
:// Let AppDelegate know that we are entering the screen (UIApplication.shared.delegate as! AppDelegate).inUserConsentScreen = true // Present the screen self.navigationController?.present(ctrller, animated: true, completion: nil)
After dismissing the
FUIUserConsentViewController
screen:viewController.dismiss(animated: true, completion: nil) // Let AppDelegate know that we are exiting the view (UIApplication.shared.delegate as! AppDelegate).inUserConsentScreen = false
## Theming
Supported class paths:
fdlFUIUserConsentPageView_title {} fdlFUIUserConsentPageView_body {} fdlFUIUserConsentPageView_actionTitle {}
Supported properties:
font-color: Color; font-style: UIFontTextStyle; text-line-clamp: Integer; text-align: NSTextAlignment;
## Attention
The delegate object with type
See moreFUIUserConsentViewControllerDelegate
is declared as a weak reference. So on deallocation it will be automatically set to nil. To keep it alive as expected, developer should retain the delegate object during the whole execution scope.Declaration
Swift
open class FUIUserConsentViewController : UIViewController, ConsentPageViewControllerDelegate, ConsentPageDisplayDelegate
-
This protocol defines a set of methods invoked based on user response to the consent forms.
See moreDeclaration
Swift
public protocol FUIUserConsentViewControllerDelegate : AnyObject
-
This class specifies a user consent form with a single page of content. For a single page form, it is not required to create the FUIUserConsentPage() and then add it to the form, since it is created automatically as part of the init.
See morelet singlepageform = FUISinglePageUserConsentForm() singlepageform.title.text = "Data Privacy" singlepageform.body.text = "Detailed text about how data privacy pertains to this app and why it is important for the user to enable this functionality" singlepageform.actionTitle.text = "Learn more about Data Privacy" singlepageform.actionHandler = { controller in let alert = UIAlertController(title: "Want Data Privacy?", message: "Be wise about your data", preferredStyle: UIAlertControllerStyle.alert) alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil)) controller.present(alert, animated: true, completion: nil) }
Declaration
Swift
open class FUISinglePageUserConsentForm : FUIUserConsentForm, FUIUserConsentPageComponent
-
This class specifies a user consent form with multiple pages of content.
See morelet page1 = FUIUserConsentPage() page1.title.text = "Data Privacy" page1.body.text = "Detailed text about how data privacy pertains to this app and why it is important for the user to enable this functionality" page1.actionTitle.text = "Learn more about Data Privacy" page1.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 page2 = FUIUserConsentPage() page2.title.text = "Security" page2.body.text = "Detailed text about how data privacy pertains to this app and why it is important for the user to enable this functionality. " page2.actionTitle.text = "Learn more about Data Privacy" page2.actionHandler = { controller in let alert = UIAlertController(title: "Security", message: "Alert for data security page", preferredStyle: UIAlertControllerStyle.alert) alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.default, handler: nil)) controller.present(alert, animated: true, completion: nil) } let userconsentpages = [page1,page2] let multipageform = FUIMultiPageUserConsentForm(pages: userconsentpages)
Declaration
Swift
open class FUIMultiPageUserConsentForm : FUIUserConsentForm
-
(formerly separate UIWebViewController and WKWebViewController)
Theming
Supported style classes
See morefdlFUIWebViewContainer fdlFUIWebViewContainer_cancelButton
Declaration
Swift
open class FUIWebViewContainer : UIViewController
-
Delegate protocol for
See moreFUIWebViewContainer
.Declaration
Swift
public protocol FUIWebViewContainerDelegate : AnyObject