---
description: Build and upload MindLyst iOS app to TestFlight for beta testing
---

## Release MindLyst to TestFlight

Push a new iOS beta build of MindLyst to TestFlight.

---

## Fresh Mac Setup (from scratch)

### 1. Install tools

```bash
xcode-select --install                     # Xcode Command Line Tools
brew install openjdk@17                    # Java 17 for Gradle/KMP
```

Then install full **Xcode** from the Mac App Store (required for iOS builds).

### 2. Sign in to Apple Developer

1. Open Xcode → Settings → Accounts → **+** → Apple ID
2. Sign in with your Apple Developer account
3. Xcode auto-downloads provisioning profiles and signing certificates

### 3. Create the Xcode project (one-time only)

MindLyst iOS uses KMP (Kotlin Multiplatform). The `.xcodeproj` must be created manually:

1. Open Xcode → File → New → Project → iOS → App
2. Settings:
   - Product Name: `MindLyst`
   - Organization Identifier: `com.mindlyst`
   - Interface: **SwiftUI**
   - Language: **Swift**
   - Save inside: `mindlyst-native/`
3. Delete the default `ContentView.swift` and `MindLystApp.swift` created by Xcode
4. Drag the existing Swift files from `iosApp/` into the Xcode project:
   - `MindLystApp.swift`, `ContentView.swift`, `MindLystTheme.swift`
   - `Components/` folder (CaptureOrb.swift, BrainChipAndTriageCard.swift)
   - `Navigation/` folder (MainTabView.swift)
   - `Screens/` folder (HomeScreen, CaptureScreen, SettingsScreen, BrainDetailScreen)
5. Link the KMP shared framework (see Step 4 of build steps below)

See `iosApp/README_SETUP.md` for more details.

### 4. Verify Gradle/KMP builds

// turbo
```bash
cd mindlyst-native && ./gradlew :shared:compileKotlinIosSimulatorArm64
```

---

## Build + Upload Steps

### 1. Build the KMP shared framework

This compiles the Kotlin shared module into an iOS framework.

```bash
cd mindlyst-native && ./gradlew :shared:compileKotlinIosArm64
```

For simulator testing:
```bash
cd mindlyst-native && ./gradlew :shared:compileKotlinIosSimulatorArm64
```

### 2. Embed the shared framework in Xcode

If not already linked:
```bash
cd mindlyst-native && ./gradlew :shared:embedAndSignAppleFrameworkForXcode
```

Or manually: Xcode → Target → Build Phases → Link Binary With Libraries → add `shared.framework`

### 3. Bump the build number

Cascade will auto-increment `CURRENT_PROJECT_VERSION` in `project.pbxproj` (both Debug and Release).
Or manually: open Xcode → Target → General → Build.

### 4. Clean build folder

// turbo
```bash
xcodebuild clean -project mindlyst-native/MindLyst.xcodeproj -scheme MindLyst -configuration Release 2>&1 | tail -3
```

### 5. Archive the app

```bash
xcodebuild archive \
  -project mindlyst-native/MindLyst.xcodeproj \
  -scheme MindLyst \
  -configuration Release \
  -archivePath build/MindLyst.xcarchive \
  -destination 'generic/platform=iOS' \
  DEVELOPMENT_TEAM=748N7QPX7J \
  CODE_SIGN_STYLE=Automatic
```

> **Note:** If using a `.xcworkspace` (e.g. with CocoaPods), replace `-project` with `-workspace`.

### 6. Export + upload to App Store Connect

```bash
xcodebuild -exportArchive \
  -archivePath build/MindLyst.xcarchive \
  -exportPath build/export \
  -exportOptionsPlist scripts/MindLystExportOptions.plist
```

The `app-store-connect` export method auto-uploads the IPA.

### 7. Enable for testers

1. Go to [App Store Connect](https://appstoreconnect.apple.com) → My Apps → MindLyst → TestFlight
2. Wait ~5-15 min for processing
3. Click the new build → add to testing group
   - **Internal Testing**: available immediately
   - **External Testing**: fill in "What to Test" notes, submit for review (~24h)

---

## Alternative: Xcode GUI

1. Open `mindlyst-native/MindLyst.xcodeproj` in Xcode
2. Scheme: **MindLyst**, destination: **Any iOS Device**
3. Product → Archive
4. Organizer → Distribute App → App Store Connect → Upload

---

## Reference

### Key Paths

| Path | Purpose |
|------|---------|
| `mindlyst-native/iosApp/` | Swift UI source files |
| `mindlyst-native/shared/` | KMP shared module (business logic) |
| `mindlyst-native/shared/build.gradle.kts` | KMP build config (iOS targets) |
| `mindlyst-native/gradle/libs.versions.toml` | Version catalog |
| `mindlyst-native/MindLyst.xcodeproj/` | Xcode project (must be created manually) |
| `scripts/MindLystExportOptions.plist` | Export options for TestFlight upload |

### Build Identity

| Field | Value |
|-------|-------|
| Team ID | `748N7QPX7J` |
| Bundle ID | `com.mindlyst.MindLyst` |
| Signing | Automatic |
| KMP Framework | `shared` (static) |
| Min iOS | 16.0 |

### KMP Architecture

```
shared/src/commonMain/   →  Business logic (Kotlin)
    ↓ compiles to
shared.framework         →  iOS static framework
    ↓ linked by
iosApp/ (SwiftUI)        →  Thin UI shell
```

All business logic lives in `shared/src/commonMain/`. iOS code in `iosApp/` is a thin UI shell.

### Troubleshooting

| Problem | Fix |
|---------|-----|
| "No signing certificate" | Xcode → Settings → Accounts → Manage Certificates → + Apple Distribution |
| "Provisioning profile" error | Xcode → Target → Signing → Enable "Automatically manage signing" |
| "Build number already exists" | Increment build number in step 3 |
| KMP build fails | Check Java 17: `java -version`. Install: `brew install openjdk@17` |
| "shared.framework not found" | Run `./gradlew :shared:embedAndSignAppleFrameworkForXcode` |
| Gradle SSL proxy error | Build on home network (corporate proxy blocks Gradle repos) |
| Processing >30 min | Check [Apple system status](https://developer.apple.com/system-status/) |
