I'm new in SwiftUI. I'm worked with UIKit and Combine framework building an architecture with ViewModel, UseCases and Repositories. All my architecture is based on the loading states. My loading states are build in this way:
/// Equivalent to @Published with `LoadingState<T, E>` property wrapper
@propertyWrapper public class Loading<T, E: Swift.Error> {
public typealias State = LoadingState<T, E>
public var wrappedValue: State {
willSet {
subject.send(newValue)
}
}
public init(wrappedValue: State) {
self.wrappedValue = wrappedValue
}
private lazy var subject = CurrentValueSubject<State, Never>(wrappedValue)
public var projectedValue: AnyPublisher<State, Never> {
return subject.eraseToAnyPublisher()
}
}
and my ViewModel works in this way:
@Loading<MyData, MyError> var myDataLoadingState = .idle
public func getMyData(ID: String) {
myDataLoadingState = .loading
myDataUseCase.execute(ID: ID)
.receive(on: DispatchQueue.main)
.sink { completion in
guard case .failure(let error) = completion else { return }
myDataLoadingState = .failure(error)
} receiveValue: { myData in
self. myDataLoadingState = .success(myData)
}
.store(in: &self.cancellables)
}
The controller works in this way:
viewModel.$myDataLoadingState
.sink { state in
switch state {
case .idle:
break
case .loading:
self.showLoader()
case .success(let myData):
print(myData)
case .failure(let error):
self.print(error)
self.hideLoader()
}
}
.store(in: &cancellables)
Can I use the loading state and my ViewModel in SwiftUI? I tried in this way but seems not works:
struct ContentView: View {
@StateObject var viewModel: MyViewModel
var body: some View {
switch viewModel.loadingState {
case .idle:
Text("Idle")
case .loading:
Text("Loading")
case .success(let myData):
Text(myData.name)
case .failure(let error):
Text(error.localizedDescription)
}
}
}
The ViewModel now is an ObservableObject
public class MyViewModel: ObservableObject {
}
Thanks in advance