This file provides guidance to AI agents when working with code in this repository.
Foundation Lab is an iOS/macOS app demonstrating Apple's Foundation Models framework (iOS 26.0+/macOS 26.0+). It accompanies the "Exploring Foundation Models" book and showcases:
- Multi-turn chat with streaming responses using
LanguageModelSession - 9 system integration tools (Weather, Web Search, Contacts, Calendar, Reminders, Location, Health, Music, Web Metadata)
- Voice interface with speech-to-text (
SpeechRecognitionStateMachine) and text-to-speech - RAG chat with document indexing and semantic search (LumoKit/VecturaKit)
- AI-powered Health Dashboard with HealthKit integration via
HealthDataManager - Dynamic schema examples for structured data generation using
@GenerableandDynamicSchemaBuilder - Multilingual support (10 languages) via
LanguageServiceandLocalizable.xcstrings
# Open in Xcode
open FoundationLab.xcodeproj
# Build from command line
xcodebuild -project FoundationLab.xcodeproj -scheme "Foundation Lab" -destination 'platform=iOS Simulator,name=iPhone 17 Pro' build
# Run on specific simulator
xcodebuild -project FoundationLab.xcodeproj -scheme "Foundation Lab" -destination 'platform=iOS Simulator,name=iPhone 17 Pro' -derivedDataPath ./build testRequirements: Xcode 26.0+, iOS 26.0+/macOS 26.0+, Apple Silicon device with Apple Intelligence.
Dependencies (SPM):
HighlightSwift- Syntax highlightingFoundationModelsTools- Foundation Models utilitiesLiquidGlasKit- UI stylingLumoKit- RAG document indexing and retrievalVecturaKit- Vector search backend
Pattern: MVVM with SwiftUI using modern Swift 6 concurrency (@MainActor, Sendable).
The main entry point for Foundation Models interactions:
let session = LanguageModelSession()
let response = try await session.respond(to: "Hello")
let stream = session.streamResponse(to: "Write a story")
let structured = try await session.respond(to: "Suggest a book", generating: BookRecommendation.self)| ViewModel | Purpose |
|---|---|
ChatViewModel.swift |
Multi-turn chat with sliding window context management, streaming responses |
VoiceViewModel.swift |
Voice input/output state machine, permission handling |
HealthChatViewModel.swift |
Health-specific chat with HealthKit tool integration |
DynamicSchemaViewModel.swift |
Dynamic schema builder state management |
RAGChatViewModel.swift |
RAG chat with document indexing and retrieval |
All ViewModels use @Observable macro and @MainActor annotation.
Tools implement a custom Tool protocol. Files follow *Tool.swift naming:
WeatherTool.swift- OpenMeteo API, no API key requiredSearch1WebSearchTool.swift- Search1API keyless web searchContactsTool.swift- System contacts searchCalendarTool.swift- Event creation/management withEventKitRemindersTool.swift- AI-assisted reminder creationLocationTool.swift- Core Location with geocodingHealthDataTool.swift- HealthKit queriesMusicTool.swift- Apple Music catalog searchWebMetadataTool.swift- URL metadata extraction
Voice/
├── VoiceView.swift # Main voice interface UI
├── VoiceViewModel.swift # State machine for voice interactions
├── Services/
│ ├── InferenceService.swift # Speech recognition and synthesis
│ └── PermissionManager.swift # Handles microphone/speech permissions
└── State/
└── SpeechRecognitionStateMachine.swift # Recognition state transitions
Health/
├── Models/ # Health-specific @Generable models
├── Tools/
│ └── HealthDataTool.swift # HealthKit integration tool
├── ViewModels/
│ └── HealthChatViewModel.swift # Health chat with predictive analytics
└── Views/
├── HealthDashboardView.swift # AI-powered health insights
├── HealthChatView.swift # Health-focused chat interface
└── Components/ # Health-specific UI components
DynamicSchemas/
├── SchemaExamplesView.swift # Schema example selection
├── BasicSchemaView.swift # Simple @Generable examples
├── ArraySchemaView.swift # Collection handling
├── EnumSchemaView.swift # Union types and enums
├── NestedSchemaView.swift # Nested object structures
├── ReferencedSchemaView.swift # Schema references
├── FormBuilderView.swift # Multi-step form generation
├── InvoiceProcessingView.swift # Complex document parsing
└── ErrorHandlingSchemaView.swift # Schema error patterns
Examples demonstrate framework capabilities with ExampleViewBase:
BasicChatView.swift- One-shot promptsJournalingView.swift- Prompts and reflective summariesCreativeWritingView.swift- Creative generationStructuredGenerationView.swift- Type-safe generationStreamingView.swift- Real-time streamingGenerationGuidesView.swift- Constrained outputs with@GuideGenerationOptionsView.swift- Temperature, tokens, fitnessHealthExampleView.swift- Health dashboard exampleRAGChatView.swift- Retrieval-augmented chat with documents
FoundationLabApp.swift
└── AdaptiveNavigationView
├── SidebarView (iPad/Mac)
│ └── TabSelection enum: examples, tools, schemas, languages, settings
└── ContentView
├── ChatView (tab)
├── ToolsView (tab)
├── ExamplesView (tab)
└── SettingsView (tab)
NavigationCoordinator.shared- Singleton for cross-tab navigation syncTabSelectionenum defines navigation destinationsAdaptiveNavigationViewswitches between TabView (iPhone) and NavigationSplitView (iPad/Mac)
// @Generable for structured generation
@Generable
struct BookRecommendation {
@Guide(description: "The title of the book")
let title: String
let author: String
}
// @Observable for state management
@Observable
final class ChatViewModel {
var messages: [Message] = []
var isStreaming: Bool = false
}- Custom
FoundationModelsErrorenum withLocalizedError FoundationModelsErrorHandlerfor framework-specific errors- User-facing errors via
@State showErrorin views
LanguageService.swift-@MainActor @Observablefor language detection/managementHealthDataManager.swift- Shared instance pattern for health data
Foundation Lab/
├── AppIntents/ # Siri Shortcuts integration (OpenChatIntent)
├── Assets.xcassets/ # App assets and icons
├── Extensions/
│ ├── Color+Extensions.swift
│ └── Transcript+TokenCounting.swift
├── FoundationLabApp.swift # App entry point
├── Models/
│ ├── AppConfiguration.swift # Constants (maxTokens, temperature)
│ ├── DataModels.swift # @Generable structs
│ ├── FoundationModelsError.swift
│ ├── NavigationCoordinator.swift
│ └── TabSelection.swift
├── Playgrounds/ # 37 learning examples (Chapter 2, 3, 8, 13)
├── Services/
│ ├── ConversationContextBuilder.swift
│ ├── LanguageService.swift
│ ├── RAGService.swift
│ └── ToolExecutor.swift
├── ViewModels/
│ ├── ChatViewModel.swift
│ ├── RAGChatViewModel.swift
│ └── VoiceViewModel.swift
├── Views/
│ ├── AdaptiveNavigationView.swift
│ ├── Chat/
│ │ ├── ChatView.swift
│ │ ├── ChatInputView.swift
│ │ ├── ChatInstructionsView.swift
│ │ └── RAGDocumentPickerView.swift
│ ├── Components/
│ │ ├── CodeDisclosure.swift
│ │ ├── GenericCardView.swift
│ │ ├── ExampleViewBase.swift
│ │ └── Spacing.swift
│ ├── Examples/
│ │ ├── ExamplesView.swift
│ │ ├── BasicChatView.swift
│ │ ├── RAGChatView.swift
│ │ ├── RAGChatView+Types.swift
│ │ ├── DynamicSchemas/
│ │ └── ...
│ ├── Languages/
│ │ ├── LanguagesView.swift
│ │ └── ProductionLanguageExampleView.swift
│ ├── SidebarView.swift
│ ├── Tools/
│ │ ├── ToolsView.swift
│ │ └── HealthToolView.swift
│ └── Voice/
│ ├── VoiceView.swift
│ └── PermissionRequestView.swift
- 10 languages: English, German, Spanish, French, Italian, Japanese, Korean, Portuguese (Brazil), Chinese (Simplified), Chinese (Traditional)
- ~450KB file with all translations
Run directly in Xcode using the #Playground directive:
- Chapter 2: 16 examples (Getting Started with Sessions)
- Chapter 3: 5 examples (Generation Options)
- Chapter 8: 9 examples (Basic Tool Use)
- Chapter 13: 7 examples (Languages)
line_length: 140/200
type_body_length: 200/300
file_length: 600/800
identifier_name:
min_length: 2/1
max_length: 40/50
type_name:
max_length: 50/60
function_body_length: 60/100
nesting:
type_level: 3/5- ViewModels: Use
@Observablemacro (not@StateObject), marked with@MainActor - Tool files: Named
*Tool.swift - ViewModel files: Named
*ViewModel.swift - Navigation: Use
NavigationStackwithnavigationDestination(for:) - Shared instances: Singleton pattern with
sharedproperty - Permissions: Handled automatically via
PermissionManager - Error handling: Use
FoundationModelsError+LocalizedError - State management:
@Statefor local,@Bindingfor parent-child,@Observablefor ViewModels
- Device must support Apple Intelligence
- Enable Apple Intelligence in Settings > Apple Intelligence
- Model availability checked via
ModelAvailabilityChecker