Swift FoundationModels Cheatsheet
29 June 2025
Tip: use the
#Playground
macro to preview your prompt outputs inside Xcode.
Quickstart
import Playgrounds
import FoundationModels
func generate() async throws {
let session = LanguageModelSession()
let response = try await session.respond(to: "Capital of England, in one word.")
// → "London"
}
Chat
Multi-turn conversation, where the model preserves the context of previous messages.
func generate() async throws {
let session = LanguageModelSession()
let responseA = try await session.respond(to: "Capital of England, in one word.")
// → "London"
let responseB = try await session.respond(to: "What about France?")
// → "Paris"
}
System Prompt
High-level instructions that have higher priority over user-provided messages.
func generate() async throws {
let session = LanguageModelSession(instructions: "Respond in one word")
let response = try await session.respond(to: "Capital of England?")
// → "London"
}
You can also use a builder pattern for more complex and dynamic prompts:
func generate() async throws {
let concise = true
let session = LanguageModelSession {
"""
You're given a country name. Output with the name of a capital for that country.
"""
"""
\(concise ? "Respond in one word" : "Respond with a full sentence")
"""
}
let response = try await session.respond(to: "England")
// → "London"
}
Structured Outputs
@Generable
struct Country {
let name: String
let capital: String
}
func generate() async throws {
let session = LanguageModelSession()
let response = try await session.respond(
generating: Country.self,
includeSchemaInPrompt: false
) {
"Get a country based on its name"
"England"
}
// → { "name": "England", "capital": "London" }
}
Guides
You can use the @Guide
macro to guardrail the output.
@Generable
struct Country {
@Guide(description: "Official country name")
let name: String
@Guide(description: "The capital city name")
let capital: String
@Guide(.count(3))
let cities: String[]
}
The full list of available guides:
// Int/Float/Double/Decimal
.minimum(1)
.maximum(10)
.range(1..10)
// Array
.minimumCount(1)
.maximumCount(10)
.count(3)
.element(.minimum(1))
// String
.constant("capital")
.anyOf(["state", "republic", "province"])
.patterns(/[A-Z]{3}/) // IATA airport code
Tool Calling
final class WeatherTool: Tool {
let name = "getWeather"
let description = "Fetches the latest weather for a given city"
@Generable
struct Arguments {
@Guide(description: "A name of a city to fetch the weather for")
let city: String
}
func call(arguments: Arguments) async throws -> ToolOutput {
let temperature = getTemperature(for: arguments.city)
guard let temperature else {
return ToolOutput("Couldn't find weather for \(arguments.city)")
}
return ToolOutput("The weather in \(arguments.city) is \(temperature)°C")
}
private func getTemperature(for city: String) -> Double? {
switch (city) {
case "London":
return 15
case "Paris":
return 17
default:
return nil
}
}
}
func generate() async throws {
let weatherTool = WeatherTool()
let session = LanguageModelSession(
tools: [weatherTool]
)
let response = try await session.respond() {
"Weather in London"
}
// → "The current temperature in London is 15.0°C."
}
Output Streaming
func generate() async throws {
let session = LanguageModelSession()
let stream = session.streamResponse() {
"Describe a country"
"England"
}
for try await partialResponse in stream {
print(partialResponse)
}
// → "England is a country"
// → "England is a country that is part of the United Kingdom"
// → "England is a country that is part of the United Kingdom, located off the northwestern coast of continental Europe."
// …
}
With structured outputs:
@Generable
struct Country {
let name: String
let capital: String
let description: String
}
func generate() async throws {
@State var country: Country.PartiallyGenerated?
let session = LanguageModelSession()
let stream = session.streamResponse(
generating: Country.self,
includeSchemaInPrompt: false
) {
"Get a country based on its name"
"England"
}
for try await partialResponse in stream {
print(partialResponse)
}
// → { "name": "England", "capital": nil, "description": nil }
// → { "name": "England", "capital": "London", "description": nil }
// → { "name": "England", "capital": "London", "description": "England is a country" }
// …
}
Check Availability
struct ContentView: View {
private let model = SystemLanguageModel.default
var body: some View {
switch model.availability {
case .available:
CountryView()
case .unavailable(.appleIntelligenceNotEnabled):
Text("Apple Intelligence has not been turned on.")
case .unavailable(.modelNotReady):
Text("Not yet ready. Try again later.")
case .unavailable(.deviceNotEligible):
FallbackView()
}
}
Tip: simulate the model unavailability by setting a custom value for “Simulated Foundation Models Availability” in the target scheme editor.