Skip to content

Instantly share code, notes, and snippets.

@moyerr
Created February 5, 2025 17:24
Show Gist options
  • Select an option

  • Save moyerr/c9cb131c832b13adf4c5e125cbbfd965 to your computer and use it in GitHub Desktop.

Select an option

Save moyerr/c9cb131c832b13adf4c5e125cbbfd965 to your computer and use it in GitHub Desktop.
A SwiftUI ViewModifier for receiving state changes in an AsyncStream
extension View {
func streamChanges<Value: Equatable & Sendable>(
of value: Value,
provideStream: @escaping @Sendable (AsyncStream<Value>) async -> Void
) -> some View {
modifier(ChangeStream(value: value, provideStream: provideStream))
}
}
private struct ChangeStream<Value: Equatable & Sendable>: ViewModifier {
@State private var continuation: AsyncStream<Value>.Continuation?
var value: Value
var provideStream: @Sendable (AsyncStream<Value>) async -> Void
init(
value: Value,
provideStream: @escaping @Sendable (AsyncStream<Value>) async -> Void
) {
self.value = value
self.provideStream = provideStream
}
func body(content: Content) -> some View {
content
.task {
let (stream, continuation) = AsyncStream<Value>.makeStream()
self.continuation = continuation
await provideStream(stream)
}
.onChange(of: value) { _, newValue in
continuation?.yield(newValue)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment