Created
August 29, 2019 12:38
-
-
Save agiguere/54f4f336d9cb8d5bd3f8a64a981fa86c to your computer and use it in GitHub Desktop.
SAP Fiori for iOS SDK Code Snippet: OnboardingErrorHandler
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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