Back to Skills

swift-architecture

verified

Design Swift app architecture with MVVM, Clean Architecture, dependency injection, and repository patterns. Use when structuring iOS/macOS projects, creating ViewModels, implementing DI, or organizing code layers.

View on GitHub

Marketplace

fusengine-plugins

fusengine/agents

Plugin

fuse-swift-apple-expert

development

Repository

fusengine/agents

plugins/swift-apple-expert/skills/swift-architecture/SKILL.md

Last Verified

January 22, 2026

Install Skill

Select agents to install to:

Scope:
npx add-skill https://github.com/fusengine/agents/blob/main/plugins/swift-apple-expert/skills/swift-architecture/SKILL.md -a claude-code --skill swift-architecture

Installation paths:

Claude
.claude/skills/swift-architecture/
Powered by add-skill CLI

Instructions

# Swift Architecture Patterns

## Recommended: MVVM + Clean Architecture

```
App/
├── Features/
│   └── UserProfile/
│       ├── Views/ProfileView.swift
│       ├── ViewModels/ProfileViewModel.swift
│       └── Models/User.swift
├── Core/
│   ├── Network/NetworkService.swift
│   ├── Persistence/DataRepository.swift
│   └── DI/Container.swift
└── Shared/
    ├── Components/
    └── Extensions/
```

## ViewModel with @Observable (iOS 17+)

```swift
import Observation

@Observable
final class ProfileViewModel {
    // State
    var user: User?
    var isLoading = false
    var error: Error?

    // Dependencies
    private let repository: UserRepositoryProtocol

    init(repository: UserRepositoryProtocol = UserRepository()) {
        self.repository = repository
    }

    @MainActor
    func loadUser(id: String) async {
        isLoading = true
        defer { isLoading = false }

        do {
            user = try await repository.fetch(id: id)
        } catch {
            self.error = error
        }
    }
}
```

## Repository Pattern

```swift
protocol UserRepositoryProtocol: Sendable {
    func fetch(id: String) async throws -> User
    func save(_ user: User) async throws
}

final class UserRepository: UserRepositoryProtocol {
    private let api: APIClientProtocol
    private let cache: CacheProtocol

    init(api: APIClientProtocol, cache: CacheProtocol) {
        self.api = api
        self.cache = cache
    }

    func fetch(id: String) async throws -> User {
        if let cached: User = cache.get(key: id) { return cached }
        let user = try await api.get("/users/\(id)")
        cache.set(key: id, value: user)
        return user
    }
}
```

## Dependency Injection with Environment

```swift
// Define environment key
private struct APIClientKey: EnvironmentKey {
    static let defaultValue: APIClientProtocol = APIClient()
}

extension EnvironmentValues {
    var apiClient: APIClientProtocol {
        get { self[APIClientKey.self] }
        set { se

Validation Details

Front Matter
Required Fields
Valid Name Format
Valid Description
Has Sections
Allowed Tools
Instruction Length:
2156 chars