agentsclimarketplace

Swift architecture

Skill Mattakushi432/Claude-Code-Skills-Custom-DevTools-Pack/plugins/devtools-pack/skills/swift-architecture

When to activate: iOS/macOS app architecture, MVVM, TCA, Clean Architecture, dependency injection, modular design in Swift appsFrom its SKILL.md

Install
npx -y skills add Mattakushi432/Claude-Code-Skills-Custom-DevTools-Pack --skill swift-architecture

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

  • 0 stars0 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.

SKILL.md

5.2 KB, ~1.1k tokens by cl100k_base, as published. Nobody here has run it

Swift App Architecture Patterns

MVVM with SwiftUI

// Model — pure data, no UI dependencies
struct Article: Identifiable, Codable {
    let id: UUID
    let title: String
    let body: String
    let publishedAt: Date
}

// ViewModel — transforms model for display, owns async operations
@MainActor
final class ArticleListViewModel: ObservableObject {
    @Published private(set) var articles: [Article] = []
    @Published private(set) var isLoading = false
    @Published var errorMessage: String?

    private let repository: any ArticleRepository

    init(repository: any ArticleRepository) {
        self.repository = repository
    }

    func load() async {
        isLoading = true
        defer { isLoading = false }
        do {
            articles = try await repository.fetchAll()
        } catch {
            errorMessage = error.localizedDescription
        }
    }
}

// View — purely declarative, no business logic
struct ArticleListView: View {
    @StateObject private var vm: ArticleListViewModel

    init(repository: any ArticleRepository) {
        _vm = StateObject(wrappedValue: ArticleListViewModel(repository: repository))
    }

    var body: some View {
        Group {
            if vm.isLoading { ProgressView() }
            else { List(vm.articles) { ArticleRow(article: $0) } }
        }
        .task { await vm.load() }
        .alert("Error", isPresented: .constant(vm.errorMessage != nil)) { }
              message: { Text(vm.errorMessage ?? "") }
    }
}

Repository Pattern

protocol ArticleRepository {
    func fetchAll() async throws -> [Article]
    func fetch(id: UUID) async throws -> Article?
    func save(_ article: Article) async throws
}

struct RemoteArticleRepository: ArticleRepository {
    let client: APIClient

    func fetchAll() async throws -> [Article] {
        try await client.get("/articles", as: [Article].self)
    }

    func fetch(id: UUID) async throws -> Article? {
        try await client.get("/articles/\(id)", as: Article.self)
    }

    func save(_ article: Article) async throws {
        try await client.post("/articles", body: article) as Article
    }
}

// In-memory implementation for tests/previews
final class InMemoryArticleRepository: ArticleRepository {
    var articles: [Article] = []
    func fetchAll() async throws -> [Article] { articles }
    func fetch(id: UUID) async throws -> Article? { articles.first { $0.id == id } }
    func save(_ article: Article) async throws { articles.append(article) }
}

Dependency Injection Container

// Using point-free/swift-dependencies style
import Dependencies

extension DependencyValues {
    var articleRepository: any ArticleRepository {
        get { self[ArticleRepositoryKey.self] }
        set { self[ArticleRepositoryKey.self] = newValue }
    }
}

private enum ArticleRepositoryKey: DependencyKey {
    static let liveValue: any ArticleRepository = RemoteArticleRepository(client: .live)
    static let testValue: any ArticleRepository = InMemoryArticleRepository()
    static let previewValue: any ArticleRepository = InMemoryArticleRepository(articles: .preview)
}

// Usage in ViewModel
@MainActor
final class ArticleListViewModel: ObservableObject {
    @Dependency(\.articleRepository) var repository
}

Clean Architecture Layers

Presentation (SwiftUI views + ViewModels)
      ↓
Domain (Use Cases / Interactors)
      ↓
Data (Repositories → Remote + Local)
// Domain layer — use case
struct FetchArticlesUseCase {
    let remote: any ArticleRepository
    let local: any ArticleRepository

    func execute() async throws -> [Article] {
        do {
            let articles = try await remote.fetchAll()
            for article in articles { try await local.save(article) }
            return articles
        } catch {
            // Fallback to local cache
            return try await local.fetchAll()
        }
    }
}

Modular Feature Design

// Each feature is a standalone SPM module
// Feature/ArticleFeature/Sources/ArticleListView.swift
public struct ArticleListView: View {
    public init(store: ArticleStore) { self.store = store }
    private let store: ArticleStore
    // ...
}

// App target wires features together
import ArticleFeature
import ProfileFeature

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            TabView {
                ArticleListView(store: .live)
                ProfileView(store: .live)
            }
        }
    }
}

Common Anti-Patterns

  • Fat ViewControllers / fat Views — move business logic to ViewModel or UseCase
  • Views depending on networking — always go through ViewModel → Repository
  • Singleton abuse — use DI instead; singletons make testing hard
  • Circular module dependencies — extract shared types to a Core module
  • Tight coupling between features — communicate via protocols or shared events, not direct imports

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Gives 0 of the 12 instructions most architecture codebase skills give in ~1.1k tokens

Counted across 811 of the 1,134 authors here whose files we hold, read 2026-08-07

  • Ask the user which candidate to explorein 45 of 811, across 15 files
  • Apply the deletion test to suspected shallow modulesin 43 of 811, across 15 files
  • Read any relevant architecture decision records firstin 31 of 811, across 8 files
  • Use exact glossary terms in every suggestionin 30 of 811, across 10 files
  • Accept dependencies instead of creating themin 24 of 811, across 5 files
  • Include before and after visualisations for each candidatein 24 of 811, across 5 files
  • Read the domain glossary before exploringin 24 of 811, across 6 files
  • Return results instead of producing side effectsin 23 of 811, across 4 files
  • Explore the codebase for shallow modules and frictionin 23 of 811, across 3 files
  • Introduce seams only where things varyin 22 of 811, across 3 files
  • Reduce the number of methodsin 21 of 811, across 2 files
  • Design deep modules with small interfacesin 21 of 811, across 3 files

Said here and by no other author read

  • move business logic to viewmodel or usecase
  • access data through viewmodel and repository
  • extract shared types to core module
  • decouple features via protocols or shared events
  • make features standalone swift package modules
  • define repositories as protocols

Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.

Keep looking

Skills are one crate of 326,679. 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.