Skip to content

Instantly share code, notes, and snippets.

@myurieff
Created February 8, 2023 15:20
Show Gist options
  • Save myurieff/f8337c2c7543e8010a7bb14d25fdafe4 to your computer and use it in GitHub Desktop.
Save myurieff/f8337c2c7543e8010a7bb14d25fdafe4 to your computer and use it in GitHub Desktop.
TCA Inputs Outputs
struct SomeFeature: ReducerProtocol {
struct State: Equatable {}
enum Action: Equatable {
case didAppear
case refreshData
case didComplete
}
struct Input {
var shouldRefresh: () -> AsyncStream<Void>
}
struct Output {
var didCompleteFlow: () -> Void
}
/// Allows plugging in events from the outside world
/// that can trigger a certain behaviour within this feature.
public let input: Input?
/// Allows notifying the outside world of certain events
/// that have happened within this feature
public let output: Output?
var body: some ReducerProtocol<State, Action> {
Reduce { state, action in
switch action {
case .didAppear:
guard let input else { return .none }
return .run { send in
for await _ in input.shouldRefresh() {
// Forward outside world event into
// our current domain
await send(.refreshData)
}
}
case .refreshData:
// do some work
return .none
case .didComplete:
return .fireAndForget {
// let the outside world know the
// user did complete the flow
output?.didCompleteFlow()
}
}
}
}
}
// USAGE:
func createScreen(
someImportantEventStream: AnyPublisher<Void, Never>,
onFlowCompletion: @escaping () -> Void
) {
let input = SomeFeature.Input {
AsyncStream(someImportantEventStream.values)
}
let output = SomeFeature.Output(didCompleteFlow: onFlowCompletion)
let store = Store(
initialState: SomeFeature.State(),
reducer: SomeFeature(
input: input,
output: output
)
)
let view = ...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment