Created
December 30, 2022 21:37
-
-
Save evandcoleman/59ebca65bf476093912f4385489e385d to your computer and use it in GitHub Desktop.
Super simple error handling in SwiftUI
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
// | |
// HandleErrors.swift | |
// App | |
// | |
// Created by Evan Coleman on 12/30/22. | |
// | |
import SwiftUI | |
// MARK: Usage Example/Preview | |
struct HandleErrorViewModifier_Previews: PreviewProvider { | |
static var previews: some View { | |
ErroringView() | |
.handleErrors() | |
} | |
struct ErroringView: View { | |
@Environment(\.handleError) var handleError | |
var body: some View { | |
Button("Trigger Error", action: { handleError(Error()) }) | |
} | |
struct Error: LocalizedError { | |
var errorDescription: String? = "This is a test error" | |
} | |
} | |
} | |
// MARK: HandleErrorAction | |
private struct HandleErrorKey: EnvironmentKey { | |
static let defaultValue: HandleErrorAction = .init(handler: { _ in }) | |
} | |
extension EnvironmentValues { | |
var handleError: HandleErrorAction { | |
get { self[HandleErrorKey.self] } | |
set { self[HandleErrorKey.self] = newValue } | |
} | |
} | |
struct HandleErrorAction { | |
var handler: (Error) -> Void | |
func callAsFunction(_ error: Error) { | |
handler(error) | |
} | |
} | |
// MARK: HandleErrorViewModifier | |
extension View { | |
func handleErrors() -> some View { | |
modifier(HandleErrorViewModifier()) | |
} | |
} | |
struct HandleErrorViewModifier: ViewModifier { | |
@State var currentError: Error? | |
private var isPresented: Binding<Bool> { | |
.init( | |
get: { currentError != nil }, | |
set: { newValue in | |
if !newValue { | |
currentError = nil | |
} | |
} | |
) | |
} | |
func body(content: Content) -> some View { | |
content | |
.alert("Oh no!", isPresented: isPresented, actions: { | |
Button(action: { currentError = nil }) { | |
Text("Dismiss") | |
} | |
}, message: { | |
Text(currentError?.localizedDescription ?? "") | |
}) | |
.environment(\.handleError, HandleErrorAction { error in | |
currentError = error | |
}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment