Skip to main content

Configuration Files

Config/Secrets.xcconfig

Location: Config/Secrets.xcconfig (gitignored)
This file contains API keys and secrets. Never commit to git!
Template: Config/Secrets.example.xcconfig
# Supabase Configuration
SUPABASE_URL = https://your-project-ref.supabase.co
SUPABASE_ANON_KEY = YOUR_PUBLIC_ANON_KEY

# RevenueCat Configuration
REVENUECAT_API_KEY = YOUR_RC_KEY
RC_ENTITLEMENT_ID = pro

# AI Proxy Configuration
PROXY_BASE_URL = https://your-project-ref.supabase.co/functions/v1
PROXY_PATH = /ai

Config/App.xcconfig

Location: Config/App.xcconfig General app configuration:
# App Identity
PRODUCT_NAME = SwiftAIBoilerplatePro
PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.yourapp
MARKETING_VERSION = 1.0.0
CURRENT_PROJECT_VERSION = 1

# Deployment Target
IPHONEOS_DEPLOYMENT_TARGET = 17.0

# Build Settings
SWIFT_VERSION = 5.10

Environment Variables

Development (DEBUG builds)

Set in Xcode Scheme → Edit Scheme → Run → Arguments → Environment Variables:
VariableDefaultPurpose
AUTH_BYPASS1 (enabled)Enable MockAuthClient
CHAT_SYNC_ENABLEDfalseEnable chat sync
CRASH_REPORTING_ENABLEDfalseEnable Crashlytics

Production (RELEASE builds)

Controlled by FeatureFlags.swift:
FeatureDefaultNotes
Mock AuthfalseAlways disabled in RELEASE
Chat SyncFeature flagOptional cloud sync
CrashlyticstrueError reporting

Feature Flags

Location: SwiftAIBoilerplatePro/Composition/FeatureFlags.swift
public enum FeatureFlags {
    // Mock Auth (DEBUG only)
    public static var shouldUseMock: Bool {
        #if DEBUG
        return ProcessInfo.processInfo.environment["AUTH_BYPASS"] != "0"
        #else
        return false
        #endif
    }
    
    // Chat Sync (Optional)
    public static var chatSyncEnabled: Bool {
        #if DEBUG
        return true  // Set to true to enable
        #else
        return ProcessInfo.processInfo.environment["CHAT_SYNC_ENABLED"] == "true"
        #endif
    }
    
    // Crashlytics
    public static var crashlyticsEnabled: Bool {
        #if DEBUG
        return false
        #else
        return true
        #endif
    }
}

Backend Configuration

Supabase

  • Development
  • Production
SUPABASE_URL = https://dev-project.supabase.co
SUPABASE_ANON_KEY = dev_anon_key
PROXY_BASE_URL = https://dev-project.supabase.co/functions/v1
Get credentials: Supabase Dashboard → Project Settings → API

OpenRouter

Set as Supabase secret:
supabase secrets set OPENROUTER_API_KEY=sk-or-v1-YOUR_KEY
Get key: OpenRouter Dashboard

RevenueCat

REVENUECAT_API_KEY = appl_YOUR_PUBLIC_KEY
RC_ENTITLEMENT_ID = pro
Get key: RevenueCat Dashboard → Settings → API Keys

CompositionRoot Configuration

Location: SwiftAIBoilerplatePro/Composition/CompositionRoot.swift The DI container reads configuration and creates appropriate implementations:
// Reads from Config/Secrets.xcconfig
let supabaseURL = ProcessInfo.processInfo.environment["SUPABASE_URL"]
let proxyBaseURL = ProcessInfo.processInfo.environment["PROXY_BASE_URL"]

// Chooses implementation based on config
if shouldUseMock {
    self.sessionManager = MockAuthClient()
} else {
    self.sessionManager = SupabaseAuthClient(...)
}

if proxyBaseURL?.isEmpty == false {
    self.llmClient = ProxyLLMClient(...)
} else {
    self.llmClient = EchoLLMClient()
}

Xcode Build Configuration

Debug vs Release

Debug (default):
  • Mock auth enabled by default
  • Detailed logging
  • Crashlytics disabled
  • No optimization
Release:
  • Real auth required
  • Production logging
  • Crashlytics enabled
  • Full optimization
Switch configuration:
Product → Scheme → Edit Scheme → Run → Build Configuration

Quick Reference

  1. Edit Scheme → Run → Environment Variables
  2. Add AUTH_BYPASS = 0
  3. Configure Supabase in Secrets.xcconfig
  4. Clean and rebuild
  1. Run SQL migration
  2. Set chatSyncEnabled = true in FeatureFlags
  3. Uncomment Supabase repositories
  4. Wire up in CompositionRoot
  1. Update Secrets.xcconfig with production URLs/keys
  2. Verify in RELEASE build configuration
  3. Archive and test
I