Skip to content

Instantly share code, notes, and snippets.

@agiguere
Created August 29, 2019 12:38
Show Gist options
  • Save agiguere/54f4f336d9cb8d5bd3f8a64a981fa86c to your computer and use it in GitHub Desktop.
Save agiguere/54f4f336d9cb8d5bd3f8a64a981fa86c to your computer and use it in GitHub Desktop.
SAP Fiori for iOS SDK Code Snippet: OnboardingErrorHandler
import SAPCommon
import SAPFiori
import SAPFioriFlows
import SAPFoundation
class OnboardingErrorHandler {
/// Onboarding error handling can be customized here
func handleOnboardingError(_ error: Error) {
switch error {
case WelcomeScreenError.demoModeRequested:
AppDelegate.shared.startDemoMode()
default:
// An error here means a critical error – the `OnboardingErrorHandler` responded with OnboardingDisposition.stop to stop the onboarding.
DispatchQueue.main.async {
AppDelegate.shared.onboardUser()
}
}
}
/// Unlocking error handling can be customized here
func handleUnlockingError(_ error: Error) {
switch error {
// We reset the OnboardingSessionManager if the user has chosen to reset their passcode
case StoreManagerError.resetPasscode, OnboardingError.cancelled:
resetOnboardingSessionManager()
// We reset the OnboardingSessionManager if the user has exceeded the maximum retry limit
case StoreManagerError.passcodeRetryLimitReached:
let alertController = UIAlertController(title: LocalizedStrings.Onboarding.passcodeRetryLimitReachedTitle, message: LocalizedStrings.Onboarding.passcodeRetryLimitReachedMessage, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: LocalizedStrings.Onboarding.resetTitle, style: .destructive) { _ in
self.resetOnboardingSessionManager()
})
presentAlertController(alertController)
default:
return
}
}
}
// MARK: - OnboardingControllerDelegate
extension OnboardingErrorHandler: OnboardingControllerDelegate {
func onboardingController(_ controller: OnboardingControlling, didFail flow: OnboardingFlow, with error: Error, completionHandler: @escaping (OnboardingErrorDisposition) -> Void) {
switch flow.flowType {
case .onboard:
onboardFailed(with: error, completionHandler: completionHandler)
case .restore:
restoreFailed(with: error, controller: controller, onboardingID: flow.context.onboardingID, completionHandler: completionHandler)
default:
completionHandler(.retry)
}
}
}
// MARK: - Private API
private extension OnboardingErrorHandler {
/// Onboarding related error handling
func onboardFailed(with error: Error, completionHandler: @escaping (OnboardingErrorDisposition) -> Void) {
switch error {
case WelcomeScreenError.demoModeRequested:
completionHandler(.stop(error))
return
default:
let alertController = UIAlertController(title: LocalizedStrings.Onboarding.failedToLogonTitle, message: error.localizedDescription, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: LocalizedStrings.Onboarding.retryTitle, style: .default) { _ in
completionHandler(.retry)
})
presentAlertController(alertController)
}
}
/// Restoring related error handling
func restoreFailed(with error: Error, controller: OnboardingControlling, onboardingID: UUID?, completionHandler: @escaping (OnboardingErrorDisposition) -> Void) {
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .alert)
switch error {
case StoreManagerError.cancelPasscodeEntry, StoreManagerError.skipPasscodeSetup, StoreManagerError.resetPasscode:
resetOnboarding(onboardingID, controller: controller, completionHandler: completionHandler)
return
case StoreManagerError.passcodeRetryLimitReached:
alertController.title = LocalizedStrings.Onboarding.passcodeRetryLimitReachedTitle
alertController.message = LocalizedStrings.Onboarding.passcodeRetryLimitReachedMessage
default:
alertController.title = LocalizedStrings.Onboarding.failedToLogonTitle
alertController.message = error.localizedDescription
alertController.addAction(UIAlertAction(title: LocalizedStrings.Onboarding.retryTitle, style: .default) { _ in
completionHandler(.retry)
})
}
alertController.addAction(UIAlertAction(title: LocalizedStrings.Onboarding.resetTitle, style: .destructive) { _ in
self.resetOnboarding(onboardingID, controller: controller, completionHandler: completionHandler)
})
presentAlertController(alertController)
}
/// Reset onboarding, then start a new onboarding flow
func resetOnboarding(_ onboardingID: UUID?, controller: OnboardingControlling, completionHandler: @escaping (OnboardingErrorDisposition) -> Void) {
guard let onboardingID = onboardingID else {
completionHandler(.retry)
return
}
(controller as? OnboardingController)?.resetFlow(for: onboardingID) { _ in
completionHandler(.retry)
}
}
// Private function that resets the OnboardingSessionManager
func resetOnboardingSessionManager() {
let sessionManager = OnboardingSessionManager.shared!
sessionManager.removeSession { _ in
DispatchQueue.main.async {
let applicationUIManager = sessionManager.presentationDelegate as? ApplicationUIManager
applicationUIManager?.releaseRootFromMemory()
sessionManager.open { _ in }
}
}
}
func presentAlertController(_ alertController: UIAlertController) {
DispatchQueue.main.async {
guard let topViewController = ModalUIViewControllerPresenter.topPresentedViewController() else {
fatalError("Invalid UI state")
}
topViewController.present(alertController, animated: true)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment