> ## 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.

# Deployment Guide

> Ship your app to TestFlight and the App Store with OpenRouter AI integration

<Info>
  Find complete deployment steps in your project [Building Your App](https://github.com/SwiftAIBoilerplatePro/SwiftAIBoilerplatePro-Distribution/blob/main/docs/BUILDING_YOUR_APP.md)
</Info>

## OpenRouter Setup

Before deploying, you need to set up the AI proxy through Supabase Edge Functions. This keeps your API keys secure on the server.

<Warning>
  Never bundle API keys in your iOS app. Keys can be extracted from the binary. Our architecture routes all AI requests through Supabase Edge Functions.
</Warning>

<Steps>
  <Step title="Generate OpenRouter API Key">
    Sign up or sign in to [OpenRouter](https://openrouter.ai):

    1. Create your first project
    2. Generate your API key

    <Note>
      This is a **private key**. We will deploy it directly to our Supabase Edge Function and never bundle it with our app or push it to git.
    </Note>
  </Step>

  <Step title="Set OpenRouter Key as Supabase Secret">
    Set your OpenRouter key as a Supabase secret:

    ```bash theme={null}
    supabase secrets set OPENROUTER_API_KEY=sk-or-your-openrouter-key
    ```

    This keeps your API key secure on the server side.
  </Step>

  <Step title="Deploy AI Edge Function">
    Deploy the AI Edge Function to Supabase:

    ```bash theme={null}
    supabase functions deploy ai
    ```

    The boilerplate includes a ready-to-deploy Edge Function that handles all AI API calls securely.
  </Step>

  <Step title="Verify Deployment">
    Verify your function is deployed:

    1. Go to **Supabase Dashboard** → **Edge Functions**
    2. See your `ai` function listed
    3. Note down the function URL
  </Step>

  <Step title="Update the proxy config">
    Open `Config/Secrets.xcconfig` in Xcode and set the base URL plus path. The function name (`ai`) is the `PROXY_PATH`, not part of `PROXY_BASE_URL`:

    ```bash theme={null}
    PROXY_BASE_URL = https://your-project-ref.supabase.co/functions/v1
    PROXY_PATH = /ai
    ```

    Then run the update script:

    ```bash theme={null}
    bash scripts/update-config.sh
    ```
  </Step>
</Steps>

## Deployment Phases

<Steps>
  <Step title="Pre-Deployment">
    * Run the full test suite (\~598 tests across 12 package test targets + the app test suites, one `Boilerplate.xctestplan` run)
    * Fix all linter warnings
    * Test on real devices
    * Update legal documents
  </Step>

  <Step title="TestFlight Beta">
    * Archive build
    * Upload to App Store Connect
    * Add internal testers
    * Gather feedback
  </Step>

  <Step title="App Store Submission">
    * Prepare metadata
    * Create screenshots
    * Submit for review
    * Monitor status
  </Step>

  <Step title="Production Launch">
    * Configure production backends
    * Monitor crashes
    * Respond to reviews
    * Plan updates
  </Step>
</Steps>

## Pre-Deployment Checklist

<AccordionGroup>
  <Accordion title="Code Quality">
    * [ ] All tests pass (⌘U)
    * [ ] No warnings in build
    * [ ] Tested on real device
    * [ ] Performance is smooth
    * [ ] No crashes in common flows
  </Accordion>

  <Accordion title="Configuration">
    * [ ] Real backends configured (not mock)
    * [ ] API keys in `Config/Secrets.xcconfig`
    * [ ] Bundle ID matches App Store Connect
    * [ ] Version number set (e.g., 1.0.0)
    * [ ] Build number set (start at 1)
  </Accordion>

  <Accordion title="Legal">
    * [ ] Privacy policy updated
    * [ ] Terms of service updated
    * [ ] Subscription terms updated
    * [ ] Privacy policy URL works
    * [ ] Terms URL works
  </Accordion>

  <Accordion title="Assets">
    * [ ] App icon (1024×1024)
    * [ ] Screenshots for all sizes
    * [ ] App description written
    * [ ] Keywords added
    * [ ] Support URL set
  </Accordion>
</AccordionGroup>

## TestFlight Deployment

### 1. Archive Build

```text theme={null}
# In Xcode
Product → Archive

# Wait for archive to complete
# Organizer window opens automatically
```

### 2. Validate Archive

```text theme={null}
# In Organizer
1. Select your archive
2. Click "Validate App"
3. Choose options:
   - Upload symbols: Yes
   - Manage version: No
4. Click "Validate"
5. Fix any errors
```

### 3. Upload to App Store

```text theme={null}
# In Organizer
1. Click "Distribute App"
2. Choose "App Store Connect"
3. Next → Upload
4. Wait for processing (~5-10 minutes)
```

### 4. Add Testers

**Internal Testers (up to 100):**

* App Store Connect → TestFlight → Internal Testing
* Add team members
* They receive email invite
* Install via TestFlight app

**External Testers (up to 10,000):**

* Create group: "Beta Testers"
* Add email addresses
* Requires beta review (1-2 days)
* Public link available

### 5. Test Thoroughly

* [ ] Sign up flow
* [ ] Chat functionality
* [ ] Subscription purchases (sandbox)
* [ ] Settings and preferences
* [ ] Performance on various devices

## App Store Submission

<Warning>
  **Run [App Store 4.3 hardening](/pages/guides/app-store-4-3-hardening) before this step.** It covers the binary `strings` audit, branding map, dead-code removal, and screenshot ordering. The most common rejection reason for boilerplate-based apps is undifferentiated product, not a metadata typo.
</Warning>

### 1. Prepare Metadata

**In App Store Connect:**

```text theme={null}
App Information:
- Name: Your App Name
- Subtitle: Short description
- Privacy Policy URL: https://yoursite.com/privacy
- Category: Productivity (or your category)
- Content Rights: Does not use third-party content
```

### 2. Create Screenshots

**Required sizes:**

* 6.7" (iPhone 15 Pro Max): 1290 × 2796
* 6.5" (older Pro Max): 1284 × 2778
* 5.5" (older Plus): 1242 × 2208
* 12.9" iPad Pro: 2048 × 2732 (if supporting iPad)

**Tips:**

* 4-10 screenshots per size
* Show key features
* Add text overlays
* First screenshot most important

### 3. Write Description

**Template:**

```markdown theme={null}
[Your App] is an AI-powered [category] that helps you [benefit].

FEATURES:
• AI Chat - Get instant answers
• Smart Conversations - History saved
• Premium Themes - Beautiful UI
• Cross-Device Sync - Access everywhere

PERFECT FOR:
• [Target audience 1]
• [Target audience 2]

PREMIUM FEATURES:
• Unlimited messages
• All AI models
• Priority support

Privacy Policy: [URL]
Terms: [URL]
```

### 4. Configure App Privacy

Answer privacy questionnaire:

**Data collected:**

* Contact Info: Email (for account)
* Identifiers: User ID (for backend)
* Usage Data: App interactions (if analytics)
* User Content: Chat messages

For each: Linked to identity, Used for app functionality

### 5. Submit for Review

```text theme={null}
# In App Store Connect
1. App Store tab → Version
2. Add screenshots
3. Add description
4. Select build
5. Submit for Review
```

**Review time:** 24-48 hours typically

## Production Configuration

### Backend Setup

<Tabs>
  <Tab title="Supabase">
    1. Use production Supabase project
    2. Verify Edge Function deployed (`supabase functions deploy ai`)
    3. Set production OpenRouter key (`supabase secrets set OPENROUTER_API_KEY=...`)
    4. Monitor API usage in Supabase dashboard
  </Tab>

  <Tab title="RevenueCat">
    1. Switch to **production API key** in `Secrets.xcconfig`
    2. Verify App Store Connect products are approved
    3. Map production products in RevenueCat offerings
    4. Test a real purchase before launch
  </Tab>

  <Tab title="OpenRouter">
    1. Add credits to your OpenRouter account
    2. Set up usage alerts and spending limits
    3. Monitor token usage in dashboard
    4. Consider rate limiting in Edge Function
  </Tab>
</Tabs>

### Final Verification

```swift theme={null}
// In SwiftAIBoilerplatePro/Composition/FeatureFlags.swift
// Crashlytics is opt-in via env var, even in Release builds.
public static var crashlyticsEnabled: Bool {
    #if DEBUG
    return false // Off by default in debug
    #else
    return ProcessInfo.processInfo.environment["CRASHLYTICS_ENABLED"] == "true"
    #endif
}
```

To turn Crashlytics on in production, set the `CRASHLYTICS_ENABLED=true` environment variable in your Release scheme (and follow the [Crashlytics setup guide](/pages/guides/crashlytics-setup)). Then verify your production secrets:

```bash theme={null}
# In Config/Secrets.xcconfig - Verify production URLs
SUPABASE_URL = https://production-project.supabase.co
REVENUECAT_API_KEY = appl_PRODUCTION_KEY
```

## Post-Launch

### Monitor

* [ ] Crashlytics dashboard (if enabled)
* [ ] App Store Connect analytics
* [ ] RevenueCat subscription metrics
* [ ] Supabase API usage
* [ ] User reviews and ratings

### Respond

* [ ] Reply to user reviews
* [ ] Fix critical bugs immediately
* [ ] Plan feature updates
* [ ] Gather user feedback

### Update Regularly

**Recommended cadence:**

* Bug fixes: As needed (1-3 days)
* Minor updates: Every 2-4 weeks
* Major features: Every 2-3 months

## Complete Guide

<Card title="View Complete Launch Checklist" icon="book" href="https://github.com/SwiftAIBoilerplatePro/SwiftAIBoilerplatePro-Distribution/blob/main/docs/BUILDING_YOUR_APP.md#launch-checklist">
  Find complete deployment checklist in your project
</Card>

## Related Resources

<CardGroup cols={2}>
  <Card title="Testing Guide" icon="flask" href="/pages/guides/testing">
    Run full test suite
  </Card>

  <Card title="Supabase Setup" icon="server" href="/pages/guides/supabase-setup">
    Production backend
  </Card>

  <Card title="RevenueCat Setup" icon="dollar" href="/pages/guides/revenuecat-setup">
    Production subscriptions
  </Card>

  <Card title="Building Guide" icon="hammer" href="/pages/guides/building-your-app">
    Complete customization
  </Card>
</CardGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Archive fails">
    * Clean build (⌘⇧K)
    * Check signing certificates
    * Verify provisioning profiles
    * Update Xcode if needed
  </Accordion>

  <Accordion title="App rejected">
    * Read rejection carefully
    * Fix specific issues mentioned
    * Update metadata if needed
    * Resubmit with explanation
    * If the rejection cites Guideline 4.3 or 4.2.6, see the [4.3 hardening recovery steps](/pages/guides/app-store-4-3-hardening#if-you-already-got-a-43-rejection)
  </Accordion>

  <Accordion title="Crashes in production">
    * Check Crashlytics logs
    * Reproduce locally
    * Fix and submit hotfix
    * Expedited review if critical
  </Accordion>
</AccordionGroup>
