    # Suno iOS App

> **Note**: This README serves both human developers and AI coding agents (Claude Code, GitHub Copilot, Cursor, Windsurf, etc.). AI development guidelines are in the final section.

## 🚀 Getting Started

For detailed onboarding documentation, reference the [iOS team documentation](https://www.notion.so/suno-ai/iOS-Onboarding-Your-First-Day-s-1f8b01573ccf806a95a4e4e53032df45?source=copy_link#1f8b01573ccf80719c36e1c727508fe6)

### Quick Setup

1. **Clone the repository**

   ```bash
   git clone <repository-url>
   cd app-ios
   ```

2. **Run the installation script**

   ```bash
   ./INSTALL
   ```

   This script automatically installs:

   - Ruby version manager and correct Ruby version
   - Bundler and all Ruby dependencies (Fastlane, etc.)
   - Homebrew dependencies including SwiftLint
   - Xcode command line tools if needed
   - Git hooks for code quality enforcement

3. **Open the project**
   ```bash
   open suno.xcodeproj
   ```

### Essential CLI Tools & Commands

This repo uses [Fastlane](https://docs.fastlane.tools/) for various CI/CD tasks, which can be invoked locally via `./fastlanew` wrapper. Additionally, [pre-commit](https://pre-commit.com/) is used for running a subset of quality checks on staged files before each commit.

You can find an overview of available commands below or see the full list in auto-generated [fastlane/README.md](fastlane/README.md) file.

| Command                                 | Description                                             |
| --------------------------------------- | ------------------------------------------------------- |
| `pre-commit run`                        | Run pre-commit checks on staged files                   |
| `pre-commit run --all-files`            | Run pre-commit checks on all files                      |
| `pre-commit install`                    | Install pre-commit hooks                                |
| `pre-commit uninstall`                  | Uninstall pre-commit hooks                              |
| `./fastlanew lint`                      | Run Swift file linting with baseline                    |
| `./fastlanew lint use_baseline:false`   | Run file linting without baseline (show all violations) |
| `./fastlanew lint update_baseline:true` | Update baseline with current violations                 |
| `./fastlanew deps`                      | Display dependency graph and target information         |
| `./fastlanew deps target:TargetName`    | Display detailed information for specific target        |
| `./fastlanew test`                      | Run all unit and UI tests                               |
| `./fastlanew clean`                     | Clean xcode workspace                                   |

## 📱 Architecture Overview

Suno is a modern iOS music creation and sharing platform that allows users to generate AI-powered music clips, discover content, and interact with a community of creators. The application is built using modern iOS development practices with SwiftUI and follows The Composable Architecture (TCA) pattern for state management and navigation.

**Technology Stack:**

- **Language**: Swift 5.10+
- **UI Framework**: SwiftUI (iOS 18+)
- **Architecture**: The Composable Architecture (TCA) 1.17.1+
- **Package Management**: Swift Package Manager
- **Minimum Deployment**: iOS 18.0

**Core Features:**

- Create AI-generated music clips from text prompts, camera, or audio recordings
- Edit and extend existing musical compositions with advanced waveform editing
- Share content across social platforms with rich media cards
- Discover trending music and follow other creators
- Organize music into playlists and manage musical library
- Engage with community through comments and social features

### The Composable Architecture (TCA) Pattern

**CRITICAL**: This entire codebase uses TCA exclusively. All new features MUST follow TCA patterns.

The application is built on **Point-Free's The Composable Architecture (TCA)**, a unidirectional data flow architecture that provides:

- **Centralized State Management**: All app state is managed through immutable data structures with clear state mutations
- **Action-Driven Updates**: User interactions and side effects flow through typed `Action` enums
- **Pure Reducers**: State transitions handled by pure functions that are easily testable
- **Dependency Injection**: External dependencies managed through TCA's dependency system
- **Composable Components**: Features can be composed and nested while maintaining separation of concerns

#### Core TCA Components

Every feature requires these four components:

1. **State**: Immutable data structure representing the feature's current state
2. **Action**: Enum defining all possible user interactions and side effects
3. **Reducer**: Pure function that processes actions and updates state
4. **View**: SwiftUI view that binds to the store

#### TCA Code Structure Template

```swift
// State - Always use @ObservableState macro
@ObservableState
struct FeatureState: Equatable {
    var isLoading = false
    var items: [Item] = []
    var error: String?
}

// Action - Use enum with associated values
enum FeatureAction {
    case viewDidLoad
    case itemTapped(Item)
    case loadItemsResponse(Result<[Item], Error>)
}

// Reducer - Implement Reducer protocol
@Reducer
struct FeatureReducer {
    var body: some ReducerOf<Self> {
        Reduce { state, action in
            switch action {
            case .viewDidLoad:
                state.isLoading = true
                return .run { send in
                    // Side effects here
                }
            // ... other cases
            }
        }
    }
}

// View - Bind to Store
struct FeatureView: View {
    let store: StoreOf<FeatureReducer>

    var body: some View {
        // View implementation
    }
}
```

### Modular Feature Architecture

The app follows a **feature-based modular architecture** with clear boundaries:

```
Sources/
├── Feature[Name]/          # Self-contained feature modules
├── [Service]Client/        # External service abstractions
├── ComponentLibrary/       # Shared UI components
├── Utilities/             # Common utilities
└── Localization/          # Multi-language support
```

Features are organized as self-contained modules in `Sources/Feature[Name]/`:

```
Sources/
├── Feature[Name]/
│   ├── [Name]Screen.swift      # Main view + reducer
│   ├── Components/             # Feature-specific UI components
│   ├── Models/                 # Feature-specific models
│   └── _Analytics.swift        # Analytics events (if needed)
```

**Key Characteristics:**

- **45 Feature Modules**: Each major user-facing feature is isolated in its own module
- **Self-Contained**: Features include their own State, Actions, Reducers, and Views
- **Clear Dependencies**: Inter-feature communication through well-defined protocols
- **Independent Development**: Teams can work on features independently with minimal conflicts

### Navigation & Coordination

**Coordinator Pattern with Destination-Based Navigation:**

- **App Coordinator**: Top-level state management (authentication, connectivity, force updates)
- **Feature Coordinators**: Handle internal feature navigation and modal presentations
- **Destination Enums**: Navigation modeled as reducer state with `@Presents` property wrappers
- **Hierarchical Structure**: Tab-based root navigation with nested navigation stacks

```swift
@ObservableState
struct ParentState {
    @Presents var destination: Destination.State?

    @Reducer
    enum Destination {
        case childFeature(ChildReducer.State)
        case sheet(SheetReducer.State)
    }
}
```

### Swift & SwiftUI Best Practices

1. **Use Modern Swift Features**:

   - Prefer `async/await` over completion handlers
   - Use `@ObservableState` macro for TCA state
   - Leverage Swift 5.10+ features and syntax

2. **SwiftUI Guidelines**:

   - Always prefer SwiftUI over UIKit
   - Use `@State`, `@Binding`, and TCA's `Store` appropriately
   - Favor composition over inheritance
   - Use ViewModifiers for reusable styling

3. **Error Handling**:
   - Use `Result<Success, Error>` for async operations
   - Implement proper error states in TCA reducers
   - Display user-friendly error messages via `FeatureToasts`

### Service Integration

All external services are abstracted through protocol-based clients:

```swift
@DependencyClient
struct APIClient {
    var fetchItems: () async throws -> [Item] = { [] }
    var createItem: (Item) async throws -> Item = { $0 }
}

extension APIClient: DependencyKey {
    static let liveValue = APIClient(
        fetchItems: { /* Live implementation */ },
        createItem: { /* Live implementation */ }
    )
}
```

**Key Service Clients:**

- **APIClient**: Type-safe OpenAPI-generated client
- **ClerkClient**: User authentication and session management
- **AdamantiumClient**: Custom media processing framework
- **AnalyticsClient**: Segment-based event tracking
- **PaywallClient**: RevenueCat subscription management
- **StatsigClient**: Feature flags and A/B testing

## 🚀 Getting Started

### Project Structure

```
Sources/
├── APIClient/              # Type-safe OpenAPI client
├── Feature*/               # 45 feature modules
├── ComponentLibrary/       # Shared UI components & design system
├── *Client/               # 25+ service abstractions
├── Utilities/             # Common utilities & extensions
├── Localization/          # Multi-language support
├── Waveform/              # Audio waveform components
└── DebugMenu/             # Development tools

suno/
├── sunoApp.swift          # App entry point
├── Config/                # Environment configurations
├── Assets.xcassets/       # App icons & images
└── StoreKit/              # In-app purchases
```

### CI/CD

CI/CD is powered by Github Actions (see `/.github/workflows`) and Fastlane (`./fastlanew`).

**📖 For comprehensive build documentation, including Xcode configuration, build settings optimization, and CI/CD workflows, see [docs/builds.md](docs/builds.md).**

#### Workflows Overview

**Build Workflows:**

- `build-command.yml` - Main build workflow for creating IPA artifacts
- `build-prod.yml` - Production build trigger
- `build-staff.yml` - Staff build trigger

**Distribution Workflows:**

- `distribute-staff.yml` - Distributes staff builds to Firebase

**Quality Assurance:**

- `ci.yml` - Standard CI checks (linting, tests)
- `ci-high-risk.yml` - Additional checks for high-risk changes

**Claude Integration:**

- `claude-pr-code-review.yml` - Automated PR code reviews
- `claude-pr-generate-description.yml` - Auto-generates PR descriptions
- `claude-action.yml` - Custom Claude actions in PR comments
- `commands-processor.yml` - Processes slash commands in PR comments

#### Authentication

In order to make private Github repos accessible by Swift Package Manager, a netrc file is setup on CI with a personal access token from [suno-ai-bot's](https://github.com/suno-ci-bot) (see `SUNO_CI_BOT_GH_TOKEN` in the repository secrets).

> **IMPORTANT**: The token is only valid for _1 year_. If you need to refresh the expired token, please post in **#pod-core** on Slack and ask for password to ci.cd@suno.com bot account

#### Distribution Strategy

**Firebase Distribution (Staff Builds):**

The app uses Firebase App Distribution for staff builds with automatic version tracking:

- **Version Tags**: Each distribution creates/updates a git tag following the pattern `{build_flavor}/v{version_name}` (e.g., `staff/v1.0.0-1`)
- **Duplicate Prevention**: Automatically skips distribution if the version tag already exists
- **Release Notes**: Generated based on build context:
  - **PR builds**: Include PR title, body, and commit history since base branch
  - **Branch builds**: Show changes compared to the default branch
  - **Main branch builds**: Show changes since the previous release tag
- **Tag Management**: Tags are automatically force-pushed to track the latest build for each version

**TestFlight Distribution (Production Builds):**

- Production builds are uploaded to TestFlight with localized release notes
- PR builds cannot be distributed via TestFlight (use Firebase instead)
- Includes "What's New" text in 13+ languages

#### Manual Overrides

**To release a new version:**

1. **Production**: Create a git tag with format `v{version_name}` (e.g., `v1.0.0-2`)
2. **Staff**: Create a git tag with format `staff/v{version_name}` (e.g., `staff/v1.0.0-2`)

The build system will automatically:

- Build the IPA for the tagged commit
- Distribute to the appropriate channel (TestFlight for production, Firebase for staff)
- Generate release notes based on changes since the previous tag

**Manual distribution commands:**

```bash
# Distribute a local build to Firebase
./fastlanew distribute_artifacts channel:firebase artifact_path:path/to/build.ipa

# Distribute a workflow artifact to Firebase
./fastlanew distribute_artifacts channel:firebase workflow_path:.github/workflows/build-staff.yml workflow_branch:main
```

### Xcode Templates

To reduce the need to write boilerplate code for new TCA files we use Xcode templates.

**Installation:**

```bash
cp -a Templates ~/Library/Developer/Xcode
```

**Usage:**

1. Select app target in Xcode (top most item in left-side folder menu)
2. File -> New -> Custom templates -> TCA
3. Enter name of store, ie `Foo` for `Foo`, `FooScreen` in a file called `FooScreen.swift`
4. Drag the created file into the desired module

### Development Workflow

1. **Feature Planning**: Break down features into TCA components
2. **Implementation**: Follow TCA patterns and existing conventions
3. **Integration**: Wire navigation and dependencies
4. **Code Quality**: Run `./fastlanew lint` to check SwiftLint rules and dependencies
5. **Testing**: Add reducer tests and UI snapshots
6. **Analytics**: Implement event tracking if needed

### Testing Strategy

1. **TCA Reducer Testing**:

   - Test state transitions with `TestStore`
   - Mock dependencies using TCA's `@Dependency` system
   - Test both success and failure scenarios

2. **UI Testing**:
   - Use Swift Snapshot Testing for UI regression tests
   - Create SwiftUI previews with mock data
   - Test different device sizes and accessibility settings

## 🤖 AI Development Guidelines

This section provides guidance for both engineers using AI tools and AI coding agents working on this codebase.

### Vibe Coding Guidelines

_For engineers using AI coding agents like Claude Code, Cursor, Windsurf, etc._

1. **Be Specific About TCA**: Always mention TCA architecture in your prompts

   ```
   "Create a new feature using The Composable Architecture (TCA) with:
   - @ObservableState struct for state management
   - Action enum with all user interactions
   - @Reducer implementing business logic
   - SwiftUI view binding to Store"
   ```

2. **Provide Context**: Reference existing similar features for consistency

   - "Look at FeatureCreateClip for navigation patterns"
   - "Follow the same error handling as FeatureProfile"
   - "Use similar analytics events as FeaturePlayer"

3. **Specify Dependencies**: Always mention which clients to use

   - "Use APIClient for network requests"
   - "Use AnalyticsClient for event tracking"
   - "Use StatsigClient for feature flags"

4. **Quality Checkpoints**: Before accepting AI-generated code, verify:

   - [ ] Uses TCA patterns correctly
   - [ ] Follows existing naming conventions
   - [ ] Includes proper error handling
   - [ ] Uses ComponentLibrary components
   - [ ] Has localized strings for UI text
   - [ ] Implements accessibility support

5. **Claude PR Assistant**:

   - To generate a PR description using Claude, set it to an empty value
   - To request a PR review from Claude, tag or mention @suno-ai/claude-code-review team
   - To perform a custom action using Claude, mention @claude in comment thread

#### Best Practices for AI-Assisted Development

- **Start Small**: Begin with individual components, then compose into features
- **Iterative Refinement**: Use AI to refactor and improve existing code
- **Test Early**: Ask AI to generate tests alongside implementation
- **Documentation**: Have AI generate SwiftUI previews and inline documentation
- **Consistency**: Reference this README in prompts for architectural compliance

### AI Agents Guidelines (Claude Code, Cursor, Windsurf)

_Direct instructions for AI coding agents working on this codebase._

#### Critical Architecture Requirements

1. **TCA Only**: This is a TCA-exclusive codebase. Never mix with other patterns (MVVM, MVC)
2. **Modern Swift**: Use Swift 5.10+ features, `async/await`, and `@ObservableState` macro
3. **SwiftUI Throughout**: Never use UIKit - always prefer SwiftUI
4. **Client Abstractions**: Always use existing service clients, never direct API calls

#### Code Generation Guidelines

**File Naming Convention:**

- Features: `FeatureName + "Screen.swift"`
- Components: Descriptive names (e.g., `ClipCard.swift`)
- Clients: `ServiceName + "Client.swift"`

**Common Pitfalls to Avoid:**

1. **Architecture Mixing**: Never mix TCA with other patterns
2. **Direct API Calls**: Always use existing Client abstractions
3. **State Mutations**: State changes must go through TCA reducers only
4. **Missing Dependencies**: Don't assume libraries are available - check Package.swift
5. **Outdated TCA Syntax**: Use latest TCA 1.17.1+ syntax with macros

**Context Awareness - Always Consider:**

1. **Existing Patterns**: Look at similar features for consistency
2. **Module Dependencies**: Check what's already imported
3. **Naming Conventions**: Follow established naming patterns
4. **Error Handling**: Implement comprehensive error states
5. **Analytics**: Add analytics events where appropriate

**UI/UX Guidelines:**

- Use `ComponentLibrary` for all UI components
- **Typography**: Use predefined styles from `TypographyV1`
- **Colors**: Use semantic colors from `Color+Suno` extensions
- **Components**: Prefer existing components over custom implementations
- **Spacing**: Use consistent patterns via `SafePadding`

**Adamantium**

- **Scripts**: metallib files built with Xcode 15.x

**Feature Creation Checklist:**

- [ ] Create feature module in `Sources/Feature[Name]/`
- [ ] Implement TCA State, Action, Reducer, View
- [ ] Add module to `Package.swift` products and targets
- [ ] Wire navigation in parent coordinator
- [ ] Add localized strings if needed
- [ ] Include analytics events
- [ ] Write reducer tests
- [ ] Create SwiftUI previews

**Code Quality Verification:**

- [ ] Uses TCA architecture correctly
- [ ] Follows existing code conventions
- [ ] Includes proper error handling
- [ ] Has localized strings for user-facing text
- [ ] Uses existing components from ComponentLibrary
- [ ] Implements proper accessibility support
- [ ] Follows Swift 5.10+ best practices

## 🚨 Critical Reminders

1. **TCA Only**: This is a TCA-exclusive codebase
2. **No UIKit**: Use SwiftUI throughout
3. **Client Abstractions**: Never bypass existing service clients
4. **Localization**: All user-facing strings must be localized
5. **Testing**: Include tests for new functionality
6. **Performance**: Consider app performance impact
7. **Security**: Never commit secrets or API keys

## 📚 Additional Resources

### Project Documentation

- [Builds & CI/CD Documentation](docs/builds.md) - Build configurations, Xcode settings, and CI/CD workflows

### External Resources

- [TCA Documentation](https://pointfreeco.github.io/swift-composable-architecture/)
- [SwiftUI Documentation](https://developer.apple.com/documentation/swiftui)
- [Apple Human Interface Guidelines](https://developer.apple.com/design/human-interface-guidelines/)

---

**Remember**: This codebase represents a production iOS app with complex requirements. Always prioritize code quality, user experience, and maintainability when working with both human developers and AI agents.
