Managing multiple states in SwiftUI views can be complex and error-prone. This post addresses the issue by introducing a consolidated generic ViewState enum, simplifying state management, reducing bugs, and enhancing maintainability.
In managing views with multiple states like displaying data, loading, and handling errors, a straightforward approach would be using three @Published properties:
class SomeViewModel: ObservableObject {
@Published var data: DataType
@Published var error: String?
@Published var isLoading: Bool
}
but this approach can lead to state inconsistencies.
For example, during data fetching:
func fetchData() {
isLoading = true
let data = await network.fetchData() // If loading is not updated here, it results in a perpetual loading state even after data is fetched.
}
This can inadvertently lead to scenarios where data is displayed alongside an endless loading indicator due to the failure to update the isLoading state correctly.
A more robust alternative to enhancing state management would be consolidating all view states. Using generics for the data type will allow the ViewState to be reused in other ViewModels.
public enum ViewState<T> {
case idle(data: T)
case loading
case error(message: String)
}
This pattern prevents the inconsistencies mentioned above. Generics allow this structure to be flexible across different data types, facilitating its reuse throughout the application. This method streamlines state management and simplifies the handling of UI updates, reducing bugs and enhancing code maintainability.
Example of use: https://github.com/fuxlud/Template_iOS_App
Comments