Offline first

Apple Intelligence on device, cloud as the fallback.

Covers Examples/Features/03-OnDeviceOrCloud.swift. You end up with a feature that answers instantly and privately on supported devices, and still works everywhere else.

Pick the model at runtime

FoundationModelsModel.orFallback returns the on-device model when the device can run it and your fallback when it can't:

let model: any LanguageModel
#if canImport(FoundationModels)
if #available(iOS 26.0, macOS 26.0, *) {
  model = FoundationModelsModel.orFallback(AnthropicModel("claude-sonnet-5"))
} else {
  model = AnthropicModel("claude-sonnet-5")
}
#else
model = AnthropicModel("claude-sonnet-5")
#endif

The canImport and availability checks keep the same file compiling on older OS versions and non-Apple platforms.

Use it like any other model

Everything downstream is identical for both branches: streaming, tools, structured output, chat sessions.

let result = try await generateText(
  model: model,
  prompt: "Summarize: Swift concurrency in one line."
)
print("[\(result.text)] via \(model.provider)/\(model.modelID)")

The print shows you which one actually ran.

Final code

OnDeviceOrCloud.swift
import AI

func summarize(_ text: String) async throws -> String {
  let model: any LanguageModel
  #if canImport(FoundationModels)
  if #available(iOS 26.0, macOS 26.0, *) {
    model = FoundationModelsModel.orFallback(AnthropicModel("claude-sonnet-5"))
  } else {
    model = AnthropicModel("claude-sonnet-5")
  }
  #else
  model = AnthropicModel("claude-sonnet-5")
  #endif

  let result = try await generateText(
    model: model,
    prompt: "Summarize in one line: \(text)"
  )
  return result.text
}

A fully offline chat screen is the same idea plus a session:

let chat = ChatSession(transport: LocalChatTransport(
  model: FoundationModelsModel(),
  system: "You are a helpful assistant."
))

On-device models covers Private Cloud Compute, guided generation, and the entitlement details.