Skip to main content

Architecture Overview

SwiftAI Boilerplate Pro uses modern iOS development patterns with clean separation of concerns.
Full technical details: See /docs/foundations/Architecture.md in your project for complete technical coverage.

Core Principles

1. MVVM Architecture

Clean separation between UI, business logic, and data: Benefits:
  • ✅ Views are dumb (no business logic)
  • ✅ ViewModels are testable (no UIKit dependencies)
  • ✅ Business logic isolated and reusable
  • ✅ Clear data flow

2. Dependency Injection

Centralized composition with CompositionRoot:
/// Central dependency injection container
/// Builds and owns all app-wide singletons and factories
@MainActor
@available(iOS 17.0, *)
public final class CompositionRoot {
    
    // MARK: - Singletons
    
    /// SwiftData model container
    public let modelContainer: ModelContainer
    
    /// HTTP client with interceptors
    public let httpClient: HTTPClient
    
    /// Keychain storage
    public let keychainStore: KeychainStore
    
    /// Auth client (SessionManager or MockAuthClient)
    public let sessionManager: AuthClient
    .
    .
    .
    // MARK: - Factory Methods
    
    /// Create ChatViewModel with injected dependencies
    public func makeChatViewModel(conversationID: UUID) -> ChatViewModel {
        ChatViewModel(
            conversationID: conversationID,
            messageRepository: messageRepository,
            llmClient: llmClient
        )
    }
}
Benefits:
  • ✅ No global singletons
  • ✅ Easy to mock for testing
  • ✅ Clear dependency graph
  • ✅ Compile-time safety

3. Protocol-Oriented Design

All external dependencies use protocols:
/// Main authentication client protocol
@available(iOS 17.0, *)
@preconcurrency
public protocol AuthClient: Sendable {
    /// Sign in with Apple ID
    func signInWithApple() async throws -> AuthUser
    
    /// Sign in with Google
    func signInWithGoogle() async throws -> AuthUser

// Implementations:
// - SupabaseAuthClient (production)
// - MockAuthClient (testing)
Benefits:
  • ✅ Swappable implementations
  • ✅ Easy testing with mocks
  • ✅ No vendor lock-in
  • ✅ Clear contracts

Module Structure

9 Swift Packages

Key principles:
  • ✅ No circular dependencies
  • ✅ Core has no dependencies
  • ✅ Features depend on services
  • ✅ Services depend on infrastructure

Data Flow

Chat Message Flow

1. User types message → ChatView
2. ChatView calls → ChatViewModel.sendMessage()
3. ChatViewModel:
   - Saves message → MessageRepository
   - Streams AI response → LLMClient
   - Updates @Published state
4. View automatically re-renders

Authentication Flow

1. User enters credentials → SignInView
2. View calls → AuthViewModel.signIn()
3. AuthViewModel calls → AuthClient.signInWithEmail()
4. AuthClient:
   - Calls Supabase API
   - Saves token → Keychain (via SessionStore)
   - Returns AuthUser
5. CompositionRoot observes auth state change
6. Navigation switches to authenticated content

Concurrency Model

Async/Await Throughout

/// Send current input text
    public func send() async {
        // 1. Validate input
        .
        .
        .
Benefits:
  • ✅ No completion handlers
  • ✅ Structured concurrency
  • ✅ MainActor for UI updates
  • ✅ Sendable for thread safety

Testing Strategy

Unit Tests

Test ViewModels and repositories in isolation:
func testSendMessage() async throws {
    let mockLLM = MockLLMClient()
    let viewModel = ChatViewModel(llmClient: mockLLM, ...)
    
    await viewModel.sendMessage("Hello")
    
    XCTAssertEqual(viewModel.messages.count, 2) // user + AI
}

Integration Tests

Test component interaction:
func testCompositionRoot() {
    let composition = CompositionRoot()
    
    // Verify all dependencies created
    XCTAssertNotNil(composition.httpClient)
    XCTAssertNotNil(composition.sessionManager)
    
    // Verify factories work
    let chatVM = composition.makeChatViewModel(conversationID: uuid)
    XCTAssertNotNil(chatVM)
}

UI Tests

Test end-to-end flows:
func testChatFlow() throws {
    let app = XCUIApplication()
    app.launch()
    
    // Navigate to chat
    app.buttons["Start Chat"].tap()
    
    // Send message
    let textField = app.textFields["messageInput"]
    textField.tap()
    textField.typeText("Hello AI")
    app.buttons["send"].tap()
    
    // Verify response appears
    XCTAssertTrue(app.staticTexts["Hello AI"].exists)
}
Coverage target: 85-90% overall

Customization Entry Points

Add New Feature

  1. Create package (if needed): Packages/FeatureX/
  2. Create models: Define SwiftData models in Storage
  3. Create repository: Data access layer
  4. Create ViewModel: Business logic
  5. Create View: SwiftUI interface
  6. Wire in CompositionRoot: Add factory method

Replace Backend

Implement the protocol:
// Want to use Firebase instead of Supabase?
class FirebaseAuthClient: AuthClient {
    func signIn(email: String, password: String) async throws -> AuthUser {
        // Firebase implementation
    }
    // ... implement other methods
}

// Update CompositionRoot:
self.sessionManager = FirebaseAuthClient(...)

Add UI Components

  1. Create component in DesignSystem/Components/
  2. Use design tokens (DSColors, DSSpacing, etc.)
  3. Add preview
  4. Add snapshot test
  5. Use in features

Best Practices Applied

  • Files ≤ 300 lines (extract components when larger)
  • One type per file
  • MARK comments for navigation
  • Grouped by responsibility
  • All errors mapped to AppError
  • User-friendly messages
  • Technical details logged
  • Never swallow errors silently
  • Clear, explicit names
  • No abbreviations in public API
  • Consistent conventions
  • Self-documenting code
  • Lazy loading (messages, images)
  • Cursor-based pagination
  • Image compression
  • Offline-first data access
  • Background sync
  • Tokens in Keychain (never UserDefaults)
  • API keys server-side only
  • PII redacted in logs
  • Row Level Security (Supabase)

Key Files

PurposeFile Location
Dependency InjectionSwiftAIBoilerplatePro/Composition/CompositionRoot.swift
Feature FlagsSwiftAIBoilerplatePro/Composition/FeatureFlags.swift
App EntrySwiftAIBoilerplatePro/SwiftAIBoilerplatePro.swift
NavigationSwiftAIBoilerplatePro/AppShell/MainTabView.swift
Auth RouterSwiftAIBoilerplatePro/AppShell/LaunchRouter.swift

Learn More

Find full technical documentation in your project: architecture-overview.md
I