import SwiftUI
struct AsyncNumbersStreamView: View {
@State private var currentNumber: Int? = nil
@State private var isStreaming = false
var body: some View {
VStack(spacing: 20) {
Text("Number: \(currentNumber.map(String.init) ?? "")")
.font(.largeTitle)
.padding()
Button("Start Stream") {
Task {
await startNumberStream()
}
}
.disabled(isStreaming)
.padding()
.background(isStreaming ? Color.gray : Color.blue)
.foregroundColor(.white)
.cornerRadius(8)
}
.padding()
}
func numberAsyncSequence() -> AsyncStream<Int> {
AsyncStream { continuation in
Task {
for number in 1...10 {
try? await Task.sleep(nanoseconds: 1_000_000_000) // 1 second
continuation.yield(number)
}
continuation.finish()
}
}
}
func startNumberStream() async {
isStreaming = true
for await number in numberAsyncSequence() {
currentNumber = number
}
isStreaming = false
}
}
struct AsyncNumbersStreamView_Previews: PreviewProvider {
static var previews: some View {
AsyncNumbersStreamView()
}
}This solution uses AsyncStream to create an asynchronous sequence that yields numbers from 1 to 10 with a 1-second delay between each.
The startNumberStream() function runs asynchronously and updates the currentNumber state as each number is received, which updates the UI.
The button triggers this async function inside a Task to run asynchronously without blocking the UI.
The button is disabled while streaming to prevent multiple streams running at once.