ios-architecture-expert

Installation
SKILL.md

iOS Architecture Expert — Clean Modular Architecture

Agent Behavior Contract

When this skill is active, follow these rules strictly:

  1. Feature modules have zero UIKit/SwiftUI imports — only Foundation. Domain models, use cases, presenters, and API/cache logic never depend on a UI framework.
  2. Define a boundary at every layer transition — protocol or closure. A layer never references a concrete type from another layer. Use a protocol when there are genuinely multiple strategies (FeedStore, HTTPClient, ResourceView, FeedCache); use a plain composed closure (() async throws -> Resource) when there is one — see rule 12.
  3. Domain models are value typesstruct, Hashable, Sendable. No classes for models.
  4. Presentation logic is framework-agnostic — presenters output view models (structs). No UIImage, UIColor, or SwiftUI types in the presentation layer.
  5. All dependency wiring happens in the Composition Root — the app target (or a dedicated CompositionRoot module). Feature modules never create their own dependencies.
  6. Tests drive the design — one test class per use case, named by behavior (CacheFeedUseCaseTests, not LocalFeedLoaderTests). Use makeSUT() factory in every test class.
  7. Test only the public API — no @testable import outside the Composition Root. Test targets use a plain import Feed; a behavior that can't be observed publicly is a missing public seam (a boundary, a return value, an injected collaborator), never a reason to widen the test's access. This is deliberately stricter than the source codebase, which uses @testable in a handful of places — the full argument and the Composition Root exception live in testability-and-seams.md.
  8. Use SPM multi-target packages for module separation — Feed (Foundation), FeediOS (UIKit), App (composition).
  9. Prefer async/await over closures/Combine for async operations. Use Task.immediate for synchronous-first execution in adapters where the deployment target allows it (iOS 26+; plain Task + observable-state tests is the documented fallback — see concurrency-at-boundaries.md).
  10. Match the project's existing test framework; default to Swift Testing for greenfield suites. For test doubles, test design, deterministic async testing, Swift Testing syntax and XCTest migration, defer to the swift-testing-expert skill. This skill keeps only the places where a testing decision is a design decision — see testability-and-seams.md. Two things that bite regardless: trackForMemoryLeaks/addTeardownBlock is XCTest-only (the Swift Testing equivalent is a test-scoping trait, ST-0007), and Swift Testing runs tests in parallel by default, so suites sharing a store URL or on-disk artifacts need .serialized.
  11. Mark shared mutable state with @MainActor — presenters, adapters, view controllers, and composition code run on the main actor.
  12. Do not add a protocol boundary that has only one implementation and no second strategy in sight — compose a closure in the Composition Root instead. Boundaries exist to select between strategies.
Installs
23
GitHub Stars
2
First Seen
Mar 3, 2026
ios-architecture-expert — swiftyjourney/ios-architecture-expert-skill