agentsclimarketplace

Ios app builder

Skill mouchegmouradian/claude-code-skills/skills/ios-app-builder

Production-ready skills that give Claude deep domain expertise. Install once, get senior-engineer-quality output from natural language.

Install
npx -y skills add mouchegmouradian/claude-code-skills --skill ios-app-builder

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Create production-quality iOS applications following Apple's official guidance and modern Swift patterns. Use when building iOS apps with Swift, SwiftUI, MVVM, Swift Concurrency (actors, async/await), SwiftData, or multi-module projects. Triggers on requests to create iOS projects, screens, ViewModels, repositories, feature modules, actors, or iOS architecture patterns.

SKILL.md

9.6 KB, as published. Nobody here has run it

iOS Development

Build iOS applications following Apple's official architecture guidance, modern Swift concurrency patterns, and SwiftUI best practices.

Quick Reference

TaskReference File
Architecture layers (UI, Domain, Data)architecture.md
SwiftUI patterns & navigationswiftui-patterns.md
Swift Actors & concurrencyactors.md
Project & build configurationproject-setup.md
Project structure & modulesmodularization.md
Testing approachtesting.md

Workflow Decision Tree

Creating a new project? → Read project-setup.md for SPM and Xcode setup → Read modularization.md for module structure → Use templates in assets/templates/

Adding a new feature? → Create feature module following modularization.md → Follow patterns in architecture.md

Building UI screens? → Read swiftui-patterns.md → Create Route + Screen + ViewModel

Setting up data layer? → Read data layer section in architecture.md → Create Repository protocol + actor implementation + @ModelActor

Working with concurrency? → Read actors.md for actors, Sendable, async/await → Follow the actor decision tree

Writing tests? → Read testing.md → Use Swift Testing framework with protocol-based test doubles

Core Principles

  1. Offline-first: Local persistence (SwiftData) is source of truth, sync with remote
  2. Unidirectional data flow: Events flow down, data flows up
  3. Reactive streams: Use AsyncSequence/AsyncStream for all data exposure
  4. Modular by feature: Each feature is self-contained via Swift Package modules
  5. Testable by design: Use protocols and test doubles, no mocking libraries
  6. Actor-isolated concurrency: Use actors for shared mutable state, @MainActor for UI

Architecture Layers

┌─────────────────────────────────────────┐
│              UI Layer                    │
│  (SwiftUI Views + @Observable VMs)      │
├─────────────────────────────────────────┤
│           Domain Layer                   │
│  (Use Cases - optional, for reuse)       │
├─────────────────────────────────────────┤
│            Data Layer                    │
│  (Repositories + DataSources)            │
└─────────────────────────────────────────┘

Module Types

App/                        # App target - entry point, navigation, @main
Features/
  ├── FeatureName/
  │   ├── Sources/          # Route, Screen, ViewModel
  │   └── Tests/            # Feature tests
Core/
  ├── Model/                # Domain models (pure Swift structs)
  ├── Data/                 # Repositories (protocols + actor implementations)
  ├── Database/             # SwiftData models, @ModelActor
  ├── Network/              # URLSession, API models, DTOs
  ├── Common/               # Shared utilities, extensions
  ├── UI/                   # Reusable SwiftUI components
  ├── DesignSystem/         # Theme, colors, typography, SF Symbols
  └── Testing/              # Test utilities, test doubles

Creating a New Feature

  1. Create feature module in Features/MyFeature/
  2. Add target to Package.swift with dependencies on Core modules
  3. Create these files:
    • MyFeatureRoute.swift - Owns ViewModel (@State), handles navigation
    • MyFeatureScreen.swift - Receives ViewModel (let), renders UI
    • MyFeatureViewModel.swift - @MainActor @Observable with individual properties

Standard File Patterns

ViewModel Pattern

Expose individual properties — SwiftUI's @Observable tracks each property accessed per view, enabling granular re-renders. Avoid wrapping state in a single enum (that forces full re-renders).

@MainActor
@Observable
final class MyFeatureViewModel {
    private(set) var items: [Item] = []
    private(set) var isLoading = false
    var errorMessage: String?

    private let repository: MyRepository

    init(repository: MyRepository) {
        self.repository = repository
    }

    func onAppear() async {
        isLoading = true
        defer { isLoading = false }
        do {
            items = try await repository.getItems()
        } catch {
            errorMessage = error.localizedDescription
        }
    }

    func deleteItem(id: String) async {
        do {
            try await repository.deleteItem(id: id)
            items.removeAll { $0.id == id }
        } catch {
            errorMessage = error.localizedDescription
        }
    }

    func refresh() async {
        await onAppear()
    }
}

Screen Pattern (Route/Screen Separation)

  • Route creates and owns the ViewModel with @State
  • Screen receives the ViewModel as let — no wrapper needed, SwiftUI auto-tracks @Observable
  • For two-way bindings (TextField, Toggle), use @Bindable locally in the body
// Route: owns ViewModel via @State, connects navigation
struct MyFeatureRoute: View {
    @State private var viewModel: MyFeatureViewModel

    init(repository: MyRepository) {
        viewModel = MyFeatureViewModel(repository: repository)
    }

    var body: some View {
        MyFeatureScreen(viewModel: viewModel)
            .task { await viewModel.onAppear() }
            .refreshable { await viewModel.refresh() }
            .navigationTitle("My Feature")
    }
}

// Screen: receives ViewModel, reads properties directly
struct MyFeatureScreen: View {
    let viewModel: MyFeatureViewModel

    var body: some View {
        List(viewModel.items) { item in
            Text(item.name)
                .swipeActions {
                    Button("Delete", role: .destructive) {
                        Task { await viewModel.deleteItem(id: item.id) }
                    }
                }
        }
        .overlay {
            if viewModel.isLoading && viewModel.items.isEmpty {
                ProgressView()
            }
        }
        .overlay {
            if let error = viewModel.errorMessage, viewModel.items.isEmpty {
                ContentUnavailableView(
                    "Error",
                    systemImage: "exclamationmark.triangle",
                    description: Text(error)
                )
            }
        }
    }
}

When to use a state enum instead: Use enum UiState only for truly mutually exclusive states like onboarding flows (step1 | step2 | step3) or auth state (loggedIn | loggedOut), where you cannot show content and loading simultaneously.

Property Wrapper Decision (WWDC 2023)

View roleWrapperExample
Creates the ViewModel@State@State private var viewModel = MyVM()
Receives from parentlet (none)let viewModel: MyVM
Needs $ bindings@Bindable@Bindable var viewModel = viewModel
Shared app-wide@Environment@Environment(AppState.self) var appState

Repository Pattern

// Protocol: defines contract, Sendable for cross-isolation use
protocol MyRepository: Sendable {
    func getItems() async throws -> [MyModel]
    func observeItems() -> AsyncStream<[MyModel]>
    func updateItem(_ item: MyModel) async throws
    func sync() async throws
}

// Implementation: actor for thread-safe shared state
actor OfflineFirstMyRepository: MyRepository {
    private let persistence: MyPersistenceActor
    private let network: NetworkClient

    init(persistence: MyPersistenceActor, network: NetworkClient) {
        self.persistence = persistence
        self.network = network
    }

    func getItems() async throws -> [MyModel] {
        try await persistence.fetchAll()
    }

    func observeItems() -> AsyncStream<[MyModel]> {
        persistence.observeAll()
    }

    func updateItem(_ item: MyModel) async throws {
        try await persistence.upsert(item)
    }

    func sync() async throws {
        let remoteItems = try await network.fetchItems()
        for item in remoteItems {
            try await persistence.upsert(item.toDomainModel())
        }
    }
}

Key Dependencies

Swift 6+ (strict concurrency)
iOS 17+ (required for @Observable, SwiftData, #Preview)
SwiftData (persistence)
Swift Testing (unit tests)
XCTest (UI tests)

Build Configuration

Use Swift Package Manager for multi-module projects:

  • Local package inside Xcode workspace
  • Each feature and core module is a separate target
  • Strict concurrency checking enabled (-strict-concurrency=complete)
  • Swift 6 language mode

See project-setup.md for complete configuration.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.