As everyone knows this year the Apple WWDC 2020 won't take place in San José due to the Covid-19 pandemic. Instead Apple...
Flux with SwiftUI and Combine
An easy conversion of a Flux Swift project using SwiftUI and Combine
In my previous post I wrote about the Flux pattern in Swift, making a simple project to explain how easy and powerful is this pattern using the WordPressFlux library.
Also since Apple introduced SwiftUI and Combine at the WWDC 2019, a lot of examples and posts appeared showing Flux as possible FRP solution.
In fact being familiar with the WordPressFlux library used in the WordPress iOS app resulted to be a big step forward in my approach with SwiftUI. Furthermore its consistency allowed me to avoid any huge refactor when I converted a project to SwiftUI.
Let me show you why!
2 structures, same flow

This is the diagram of the Info section of the application I made as test and as you can see the only main difference (except the presentation layer) is on the view model.
import Foundation
import WordPressFlux
import Combine
class InfoViewModel<Service: RemoteService>: ObservableObject {
@Published private (set) var state: FetchingStatus = .idle
var sections: [InfoSection] {
return store.getSections()
}
private var storeReceipt: Receipt?
private let store: InfoStore<Service>
init(store: InfoStore<Service>) {
self.store = store
storeReceipt = store.onStateChange { [weak self] (_, state) in
self?.state = state.status
}
}
func fetchInfo() {
store.onDispatch(InfoStoreAction.fetch)
}
}
First thing, the Observable protocol is replaced by ObservableObject, which is introduced by the Combine module. This means our view model will be implemented as ObservedObject.
@ObservedObject private var viewModel: InfoViewModel<PizzeriaService>
The Dispatcher is removed and the state property doesn’t need to emit the change in its didSet because of the property wrapper @Published.
When the view model will be implemented in our view it will be declared as @ObservedObject
@ObservedObject private var viewModel: InfoViewModel<PizzeriaService>
and instead of updating the view in viewModel.onChange the view will be updated when self.viewModel.state will change
var body: some View {
NavigationView {
viewForState(self.viewModel.state)
.navigationBarTitle(Text(Constants.ScreenTitles.info), displayMode: .inline)
.navigationViewStyle(StackNavigationViewStyle())
}
.onAppear {
self.viewModel.fetchInfo()
}
}
And that’s it!
You can find the new SwiftUI + Combine + Flux project here