Generate Text
generateText is the simplest language-model entry point. It sends a prompt, waits for completion, and returns an AIResponse.
let response = try await generateText(
model: model,
prompt: "Draft a friendly push notification for a habit tracker."
)
print(response.text)| Use case | Pattern |
|---|---|
| Classification | Keep temperature low and ask for a short label or reason |
| Summarization | Add a role-specific system prompt and cap output with maxTokens |
| Copy generation | Increase temperature slightly and keep provider metadata for review |
| Background jobs | Use the full AIResponse for usage, finish reason, and logs |
| Tests and mocks | Pass a direct model value instead of relying on global configuration |
Response Metadata
AIResponse keeps provider metadata beside the generated text:
let response = try await generateText(model: model, prompt: "Name this feature.")
let text = response.text
let modelName = response.model
let usage = response.usage
let finishReason = response.finishReason
print(text)
print("input:", usage?.inputTokens ?? 0)
print("output:", usage?.outputTokens ?? 0)usage, model, and finishReason are optional because not every provider returns them for every request.
TokenUsage exposes inputTokens, outputTokens, optional totalTokens, and optional cachedInputTokens. The full AIResponse initializer is AIResponse(text:model:usage:finishReason:), which is useful in custom providers and test doubles.
Errors
SDK calls throw AIError. The cases are:
| Case | When |
|---|---|
networkError(Error) | The transport failed (DNS, timeout, TLS, cancellation wrapped from URLSession) |
apiError(statusCode: Int, message: String) | The provider returned a non-2xx HTTP response |
invalidResponse | The provider returned a response that could not be parsed at all |
encodingError(Error) / decodingError(Error) | Request encoding or response decoding threw |
providerNotConfigured(String) | A model string used a provider prefix that AI.configure was not called for |
invalidModelString(String) | A model string is not in "provider/model" shape |
unsupportedFeature(String) | The resolved provider cannot perform the requested operation |
toolNotFound(String) | The model called a tool name that was not registered |
maxStepsExceeded(Int) | A tool loop hit its maxSteps cap |
schemaValidationFailed([AISchemaValidationIssue]) | generateObject decoded JSON that violates the schema |
AIError conforms to LocalizedError, so error.localizedDescription returns a readable message for logs and UI.
System Prompt And Sampling
Use GenerationOptions to describe behavior that belongs to one request:
let response = try await generateText(
model: model,
prompt: "Explain this crash log to a junior iOS engineer.",
options: GenerationOptions(
system: "You are a senior iOS engineer. Be direct and specific.",
temperature: 0.2,
maxTokens: 500
)
)Multimodal Prompt Overload
When the provider supports it, generateText can take message parts instead of a single string:
let response = try await generateText(
model: model,
prompt: [
.text("Describe the important UI details in this screenshot."),
.imageURL(URL(string: "https://example.com/screenshot.png")!, detail: .high)
]
)The text-only overload is still the best default. Use message parts when you need images, PDFs, audio, video, or files in the prompt.
Registry Form
If the app uses AI.configure, you can pass a model string:
let response = try await generateText(
model: "openai/gpt-4o-mini",
prompt: "Write a short changelog entry."
)For reusable libraries, direct model values are easier to inject and test.