From e9d7ba3352e50d5ed78d98f96fb150c055201983 Mon Sep 17 00:00:00 2001 From: Fernando Olivares Date: Tue, 19 Mar 2024 20:28:19 -0600 Subject: [PATCH 1/6] Hide retry button in ErrorView if no handler is given --- .../Helpers/ErrorPresenter.swift | 20 +++++++++++-------- .../TurboNavigatorDelegate.swift | 4 ++-- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/Source/Turbo Navigator/Helpers/ErrorPresenter.swift b/Source/Turbo Navigator/Helpers/ErrorPresenter.swift index 655571d..772215d 100644 --- a/Source/Turbo Navigator/Helpers/ErrorPresenter.swift +++ b/Source/Turbo Navigator/Helpers/ErrorPresenter.swift @@ -3,13 +3,14 @@ import SwiftUI public protocol ErrorPresenter: UIViewController { typealias Handler = () -> Void - func presentError(_ error: Error, handler: @escaping Handler) + func presentError(_ error: Error, handler: Handler?) } public extension ErrorPresenter { - func presentError(_ error: Error, handler: @escaping () -> Void) { - let errorView = ErrorView(error: error) { [unowned self] in - handler() + func presentError(_ error: Error, handler: Handler?) { + let errorView = ErrorView(error: error, + shouldShowRetryButton: (handler != nil)) { [unowned self] in + handler?() self.removeErrorViewController() } @@ -34,6 +35,7 @@ extension UIViewController: ErrorPresenter {} private struct ErrorView: View { let error: Error + let shouldShowRetryButton: Bool let handler: ErrorPresenter.Handler? var body: some View { @@ -49,10 +51,12 @@ private struct ErrorView: View { .font(.body) .multilineTextAlignment(.center) - Button("Retry") { - handler?() + if shouldShowRetryButton { + Button("Retry") { + handler?() + } + .font(.system(size: 17, weight: .bold)) } - .font(.system(size: 17, weight: .bold)) } .padding(32) } @@ -64,7 +68,7 @@ private struct ErrorView_Previews: PreviewProvider { domain: "com.example.error", code: 1001, userInfo: [NSLocalizedDescriptionKey: "Could not connect to the server."] - )) {} + ), shouldShowRetryButton: true) {} } } diff --git a/Source/Turbo Navigator/TurboNavigatorDelegate.swift b/Source/Turbo Navigator/TurboNavigatorDelegate.swift index e6fa123..a6b36a9 100644 --- a/Source/Turbo Navigator/TurboNavigatorDelegate.swift +++ b/Source/Turbo Navigator/TurboNavigatorDelegate.swift @@ -20,7 +20,7 @@ public protocol TurboNavigatorDelegate: AnyObject { /// An error occurred loading the request, present it to the user. /// Retry the request by executing the closure. /// - Important: If not implemented, will present the error's localized description and a Retry button. - func visitableDidFailRequest(_ visitable: Visitable, error: Error, retry: @escaping RetryBlock) + func visitableDidFailRequest(_ visitable: Visitable, error: Error, retry: RetryBlock?) /// Respond to authentication challenge presented by web servers behing basic auth. /// If not implemented, default handling will be performed. @@ -44,7 +44,7 @@ public extension TurboNavigatorDelegate { .openViaSafariController } - func visitableDidFailRequest(_ visitable: Visitable, error: Error, retry: @escaping RetryBlock) { + func visitableDidFailRequest(_ visitable: Visitable, error: Error, retry: RetryBlock?) { if let errorPresenter = visitable as? ErrorPresenter { errorPresenter.presentError(error, handler: retry) } From 0bd17babd6b86635c79d859854cccd8b9112c7e2 Mon Sep 17 00:00:00 2001 From: Fernando Olivares Date: Tue, 19 Mar 2024 20:51:02 -0600 Subject: [PATCH 2/6] Rename handler and add documentation --- .../Turbo Navigator/Helpers/ErrorPresenter.swift | 16 ++++++++++++---- .../Turbo Navigator/TurboNavigatorDelegate.swift | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/Source/Turbo Navigator/Helpers/ErrorPresenter.swift b/Source/Turbo Navigator/Helpers/ErrorPresenter.swift index 772215d..198feaa 100644 --- a/Source/Turbo Navigator/Helpers/ErrorPresenter.swift +++ b/Source/Turbo Navigator/Helpers/ErrorPresenter.swift @@ -3,14 +3,22 @@ import SwiftUI public protocol ErrorPresenter: UIViewController { typealias Handler = () -> Void - func presentError(_ error: Error, handler: Handler?) + func presentError(_ error: Error, retryHandler: Handler?) } public extension ErrorPresenter { - func presentError(_ error: Error, handler: Handler?) { + + /// Presents an error in a full screen view. + /// The error view will display a `Retry` button if `retryHandler != nil`. + /// Tapping `Retry` will call `retryHandler?()` then dismiss the error. + /// + /// - Parameters: + /// - error: <#error description#> + /// - retryHandler: <#retryHandler description#> + func presentError(_ error: Error, retryHandler: Handler?) { let errorView = ErrorView(error: error, - shouldShowRetryButton: (handler != nil)) { [unowned self] in - handler?() + shouldShowRetryButton: (retryHandler != nil)) { [unowned self] in + retryHandler?() self.removeErrorViewController() } diff --git a/Source/Turbo Navigator/TurboNavigatorDelegate.swift b/Source/Turbo Navigator/TurboNavigatorDelegate.swift index a6b36a9..3a77121 100644 --- a/Source/Turbo Navigator/TurboNavigatorDelegate.swift +++ b/Source/Turbo Navigator/TurboNavigatorDelegate.swift @@ -46,7 +46,7 @@ public extension TurboNavigatorDelegate { func visitableDidFailRequest(_ visitable: Visitable, error: Error, retry: RetryBlock?) { if let errorPresenter = visitable as? ErrorPresenter { - errorPresenter.presentError(error, handler: retry) + errorPresenter.presentError(error, retryHandler: retry) } } From 7db075096dbb7af097f1e21c07f146022e6adf54 Mon Sep 17 00:00:00 2001 From: Fernando Olivares Date: Tue, 19 Mar 2024 20:52:38 -0600 Subject: [PATCH 3/6] Add more docs --- Source/Turbo Navigator/Helpers/ErrorPresenter.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Source/Turbo Navigator/Helpers/ErrorPresenter.swift b/Source/Turbo Navigator/Helpers/ErrorPresenter.swift index 198feaa..8b8894b 100644 --- a/Source/Turbo Navigator/Helpers/ErrorPresenter.swift +++ b/Source/Turbo Navigator/Helpers/ErrorPresenter.swift @@ -13,8 +13,8 @@ public extension ErrorPresenter { /// Tapping `Retry` will call `retryHandler?()` then dismiss the error. /// /// - Parameters: - /// - error: <#error description#> - /// - retryHandler: <#retryHandler description#> + /// - error: presents the data in this error + /// - retryHandler: a user-triggered action to perform in case the error is recoverable func presentError(_ error: Error, retryHandler: Handler?) { let errorView = ErrorView(error: error, shouldShowRetryButton: (retryHandler != nil)) { [unowned self] in From e6ac331e2c15081d2573d2a99f09394cb3784e42 Mon Sep 17 00:00:00 2001 From: Joe Masilotti Date: Tue, 19 Mar 2024 21:11:59 -0700 Subject: [PATCH 4/6] Update demo app to use new parameter name --- Demo/SceneController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Demo/SceneController.swift b/Demo/SceneController.swift index dc32179..c09c1cd 100644 --- a/Demo/SceneController.swift +++ b/Demo/SceneController.swift @@ -94,7 +94,7 @@ extension SceneController: TurboNavigatorDelegate { if let turboError = error as? TurboError, case let .http(statusCode) = turboError, statusCode == 401 { promptForAuthentication() } else if let errorPresenter = visitable as? ErrorPresenter { - errorPresenter.presentError(error, handler: retry) + errorPresenter.presentError(error, retryHandler: retry) } else { let alert = UIAlertController(title: "Visit failed!", message: error.localizedDescription, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil)) From 1005ee249ee88a21cf7704646058a167dd437379 Mon Sep 17 00:00:00 2001 From: Joe Masilotti Date: Tue, 19 Mar 2024 21:13:42 -0700 Subject: [PATCH 5/6] Rename parameter to match new naming --- Demo/SceneController.swift | 4 ++-- Source/Turbo Navigator/TurboNavigatorDelegate.swift | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Demo/SceneController.swift b/Demo/SceneController.swift index c09c1cd..0ad7ee4 100644 --- a/Demo/SceneController.swift +++ b/Demo/SceneController.swift @@ -90,11 +90,11 @@ extension SceneController: TurboNavigatorDelegate { } } - func visitableDidFailRequest(_ visitable: Visitable, error: Error, retry: @escaping RetryBlock) { + func visitableDidFailRequest(_ visitable: Visitable, error: Error, retryHandler: RetryBlock?) { if let turboError = error as? TurboError, case let .http(statusCode) = turboError, statusCode == 401 { promptForAuthentication() } else if let errorPresenter = visitable as? ErrorPresenter { - errorPresenter.presentError(error, retryHandler: retry) + errorPresenter.presentError(error, retryHandler: retryHandler) } else { let alert = UIAlertController(title: "Visit failed!", message: error.localizedDescription, preferredStyle: .alert) alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil)) diff --git a/Source/Turbo Navigator/TurboNavigatorDelegate.swift b/Source/Turbo Navigator/TurboNavigatorDelegate.swift index 3a77121..12e6cb9 100644 --- a/Source/Turbo Navigator/TurboNavigatorDelegate.swift +++ b/Source/Turbo Navigator/TurboNavigatorDelegate.swift @@ -20,7 +20,7 @@ public protocol TurboNavigatorDelegate: AnyObject { /// An error occurred loading the request, present it to the user. /// Retry the request by executing the closure. /// - Important: If not implemented, will present the error's localized description and a Retry button. - func visitableDidFailRequest(_ visitable: Visitable, error: Error, retry: RetryBlock?) + func visitableDidFailRequest(_ visitable: Visitable, error: Error, retryHandler: RetryBlock?) /// Respond to authentication challenge presented by web servers behing basic auth. /// If not implemented, default handling will be performed. @@ -44,9 +44,9 @@ public extension TurboNavigatorDelegate { .openViaSafariController } - func visitableDidFailRequest(_ visitable: Visitable, error: Error, retry: RetryBlock?) { + func visitableDidFailRequest(_ visitable: Visitable, error: Error, retryHandler: RetryBlock?) { if let errorPresenter = visitable as? ErrorPresenter { - errorPresenter.presentError(error, retryHandler: retry) + errorPresenter.presentError(error, retryHandler: retryHandler) } } From 58abd0843ffb1f5e5d76acc7d58e8335cef44fb4 Mon Sep 17 00:00:00 2001 From: Joe Masilotti Date: Tue, 19 Mar 2024 21:17:13 -0700 Subject: [PATCH 6/6] No need to capture self, this isn't a block --- Source/Turbo Navigator/Helpers/ErrorPresenter.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Source/Turbo Navigator/Helpers/ErrorPresenter.swift b/Source/Turbo Navigator/Helpers/ErrorPresenter.swift index 8b8894b..c2f583e 100644 --- a/Source/Turbo Navigator/Helpers/ErrorPresenter.swift +++ b/Source/Turbo Navigator/Helpers/ErrorPresenter.swift @@ -16,8 +16,7 @@ public extension ErrorPresenter { /// - error: presents the data in this error /// - retryHandler: a user-triggered action to perform in case the error is recoverable func presentError(_ error: Error, retryHandler: Handler?) { - let errorView = ErrorView(error: error, - shouldShowRetryButton: (retryHandler != nil)) { [unowned self] in + let errorView = ErrorView(error: error, shouldShowRetryButton: (retryHandler != nil)) { retryHandler?() self.removeErrorViewController() }