Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.swiftaiboilerplate.com/llms.txt

Use this file to discover all available pages before exploring further.

Full technical details in your project at /docs/modules/Core.md

What’s new in v2.0

  • DeepLinkBus and ToastCenter are now @Observable. Consumers that used .onReceive($center.currentToast) should migrate to .onChange(of: center.currentToast). SwiftUI’s new observation machinery does the rest.
  • Swift 6 strict concurrency across the package.

What You Get

  • AppError enum - Maps all system errors to user-friendly messages
  • AppLogger - OSLog-based with automatic PII redaction
  • ResultOrError - Functional error handling patterns
  • Theme types - UserThemePreference enum
  • Zero dependencies - Pure foundation layer
Time saved: 6-10 hours of error handling boilerplate, logging infrastructure, and testing.

Key Components

AppError (Production Type)

Here’s a shortened version of the production enum from the boilerplate:
public enum AppError: Error, Equatable, CustomStringConvertible, LocalizedError, Sendable {
    case network(code: Int, message: String?)
    case decoding
    case unauthorized
    case rateLimited(retryAfter: TimeInterval?)
    // Additional cases omitted for brevity.

    // User-friendly messages
    public var userMessage: String {
        switch self {
        case .network(_, let message) where message?.localizedCaseInsensitiveContains("offline") == true:
            return "You're offline. Please check your internet connection."
        case .network(_, let message) where message?.localizedCaseInsensitiveContains("timeout") == true:
            return "Request timed out. Please try again."
        case .unauthorized:
            return "Please sign in to continue."
        case .rateLimited:
            return "Too many requests. Please wait a moment and try again."
        // ... handles all cases with actionable messages
        }
    }
}
SignInViewModel:
// From SwiftAIBoilerplatePro/AppShell/SignInView.swift
func signInWithApple() async {
    do {
        _ = try await authClient.signInWithApple()
        errorMessage = nil
    } catch {
        let appError = AppError.from(error)  // Auto-maps to AppError
        errorMessage = appError.userMessage  // Show friendly message to user
        AppLogger.error("Apple sign in failed: \(error)", category: AppLogger.ui)
    }
}
Production Value:
  • ✅ Auto-maps URLError, NSError, custom errors
  • ✅ Preserves technical details for logging
  • ✅ Provides actionable user messages
  • ✅ Sendable for Swift 6 compatibility
  • ✅ Equatable for testing

AppLogger

Structured logging with PII redaction:
// Usage
AppLogger.debug("Message sent", category: AppLogger.ui)
AppLogger.info("API call succeeded", category: .networking)
AppLogger.error("Failed to save", category: .storage)

// Auto-redacts sensitive data
AppLogger.debug("Token: \(.redacted(token))")
Categories:
  • .subsystem - Application subsystem
  • .ui - User interface events
  • .networking - HTTP requests
  • .storage - Database operations
  • .auth - Authentication flows
  • .ai - LLM interactions
  • .feature - Feature operations
  • .notifications - Notification operations

Customization Examples

Add Custom Error Type

// In AppError
case myFeature(reason: MyFeatureErrorReason)

enum MyFeatureErrorReason {
    case invalidInput
    case processingFailed
}

// Add user message
var userMessage: String {
    switch self {
    case .myFeature(.invalidInput):
        return "Please check your input"
    case .myFeature(.processingFailed):
        return "Processing failed. Please try again"
    }
}

Add Custom Log Category

extension AppLogger {
    static let myFeature = OSLog(
        subsystem: subsystem,
        category: "MyFeature"
    )
}

// Use it
AppLogger.info("Feature initialized", category: .myFeature)

Key Files

ComponentLocation
AppErrorPackages/Core/Sources/Core/AppError.swift
AppLoggerPackages/Core/Sources/Core/AppLogger.swift
DiagnosticsPackages/Core/Sources/Core/Diagnostics/

Dependencies

  • None - Core has zero dependencies (by design)

Used By

  • ✅ All other modules (foundation layer)
  • ✅ ViewModels (error handling)
  • ✅ Services (logging)

Best Practices

  • Always map errors to AppError
  • Use specific error reasons
  • Provide actionable user messages
  • Log technical details separately
  • Never use print() (banned by linter)
  • Choose appropriate log level
  • Use correct category
  • Redact PII automatically

Learn More

Full Documentation

Complete Core guide

Networking Module

Uses Core for errors and logging

Storage Module

Uses Core for error handling

Architecture

See how Core fits in

Test Coverage

96%+ - Highest coverage in the codebase Tests include:
  • Error mapping scenarios
  • Logger output verification
  • PII redaction
  • Category filtering