Last active
October 16, 2024 12:28
-
-
Save morajabi/3020dc40b7eb23a37c99a409e5a865de to your computer and use it in GitHub Desktop.
Form state management in Swift UI
This file contains 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 SwiftUI | |
struct FormStateData { | |
var loading: Bool | |
var error: String? | |
var succeeded: Bool? | |
} | |
// A helper for easier state management for simple forms | |
class FormState: ObservableObject { | |
@Published private(set) var state: FormStateData | |
// Streamlined access | |
var isLoading: Bool { state.loading } | |
var hasError: String? { state.error } | |
var hasSucceeded: Bool? { state.succeeded } | |
init() { | |
self.state = FormStateData(loading: false, error: nil, succeeded: nil) | |
} | |
func reset() { | |
state = FormStateData(loading: false, error: nil, succeeded: nil) | |
} | |
func startLoading() { | |
state = FormStateData(loading: true, error: nil, succeeded: nil) | |
} | |
func failed(error: String?) { | |
state = FormStateData(loading: false, error: error, succeeded: false) | |
} | |
func succeeded() { | |
state = FormStateData(loading: false, error: nil, succeeded: true) | |
} | |
} |
Refactored FormStateData to use enum instead of struct
import SwiftUI
public enum FormStateData: Equatable {
case idle
case loading
case error(String?)
case succeeded
}
// A helper for easier state management for simple forms
public class FormStateObject: ObservableObject {
@Published public private(set) var state: FormStateData
public var isLoading: Bool {
state == FormStateData.loading
}
public init() {
self.state = .idle
}
public func reset() {
state = .idle
}
public func startLoading() {
state = .loading
}
public func failed(error: String?) {
state = .error(error)
}
public func succeeded() {
state = .succeeded
}
}
@propertyWrapper
@MainActor
public struct FormState: DynamicProperty {
@StateObject private var state = FormStateObject()
public init() {}
public var wrappedValue: FormStateObject {
state
}
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
You can also use it as a property wrapper by modifying it like this:
Usage: