SwiftyAISwiftyAI

Search documentation

Find a docs page by title or section

1

Stream Text

streamText returns an AsyncThrowingStream<AIStreamChunk, Error>. Each chunk contains text and may include usage or finish reason when the provider emits final metadata.

NeedUse
Append text into a view modelIterate the returned stream and update state per chunk
Track analyticsUse onChunk for first-token timing and onFinish for usage
Cancel generationCancel the Swift Task that is consuming the stream
Smooth local demosWrap a model with streaming utilities
Chat stateUse AIChat when the UI is a normal message list

Basic Stream

var output = ""
 
for try await chunk in streamText(
    model: model,
    prompt: "Write a calm loading message for a finance dashboard."
) {
    output += chunk.text
}

Use this in SwiftUI by appending chunks to @State, an @Observable view model, or the built-in AIChat helper.

Callbacks

Callbacks are useful when you want side effects without moving all work into the for await loop.

let stream = streamText(
    model: model,
    prompt: "Generate a three-line release summary.",
    onChunk: { chunk in
        print("chunk:", chunk.text)
    },
    onFinish: { response in
        print("tokens:", response.usage?.totalTokens ?? 0)
        print("finish:", response.finishReason ?? "unknown")
    }
)
 
for try await chunk in stream {
    print(chunk.text, terminator: "")
}

onFinish receives the accumulated AIResponse.

Cancellation

There is no separate abort object. Use normal Swift task cancellation.

let task = Task {
    for try await chunk in streamText(model: model, prompt: "Write a long story.") {
        print(chunk.text, terminator: "")
    }
}
 
task.cancel()

Provider requests and local stream helpers check cancellation as they yield.

Streaming Chat History

Streaming models also support chat history:

let messages = [
    ChatMessage(role: .system, content: "Answer like a concise support engineer."),
    ChatMessage(role: .user, content: "Why did my export fail?")
]
 
for try await chunk in model.stream(messages: messages) {
    print(chunk.text, terminator: "")
}

Use message management when history needs pruning.

Related docs

For UI state, read AIChat. For simulated or smoothed streams, read streaming utilities.