Skip to content

Instantly share code, notes, and snippets.

@AlexGladkov
Created July 26, 2021 08:22
Show Gist options
  • Save AlexGladkov/a00e228271b93a819b85c19e71736139 to your computer and use it in GitHub Desktop.
Save AlexGladkov/a00e228271b93a819b85c19e71736139 to your computer and use it in GitHub Desktop.
SwiftUI + Kotlin Flow
struct ExampleView: View {
let viewModel: AuthViewModel = AuthViewModel()
var body: some View {
ObservingView(statePublisher: asPublisher(viewModel.viewStates()),
actionPublisher: asPublisher(viewModel.viewActions()),
content: { state, action in
// your view here
})
}
private class ObservableModel<State, Action>: ObservableObject {
@Published var state: State?
@Published var action: Action?
init(statePublisher: AnyPublisher<State, Never>,
actionPublisher: AnyPublisher<Action, Never>) {
statePublisher
.compactMap { $0 }
.receive(on: DispatchQueue.main)
.assign(to: &$state)
actionPublisher
.compactMap { $0 }
.receive(on: DispatchQueue.main)
.assign(to: &$action)
}
}
public struct ObservingView<State, Action, Content>: View where Content: View {
@ObservedObject private var model: ObservableModel<State, Action>
private let content: (State, Action?) -> Content
public init(statePublisher: AnyPublisher<State, Never>,
actionPublisher: AnyPublisher<Action, Never>,
@ViewBuilder content: @escaping (State, Action?) -> Content) {
self.model = ObservableModel(statePublisher: statePublisher,
actionPublisher: actionPublisher)
self.content = content
}
public var body: some View {
let view: AnyView
if let state = self.model.state {
view = AnyView(content(state, model.action))
} else {
view = AnyView(Text("Render error"))
}
return view
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment