ios-architecture-expert
Installation
SKILL.md
iOS Architecture Expert — Clean Modular Architecture
Agent Behavior Contract
When this skill is active, follow these rules strictly:
- Feature modules have zero UIKit/SwiftUI imports — only Foundation. Domain models, use cases, presenters, and API/cache logic never depend on a UI framework.
- Define protocol boundaries at every layer transition —
FeedStore,HTTPClient,ResourceView,FeedCache, etc. Concrete types live behind protocols. - Domain models are value types —
struct,Hashable,Sendable. No classes for models. - Presentation logic is framework-agnostic — presenters output view models (structs). No
UIImage,UIColor, or SwiftUI types in the presentation layer. - All dependency wiring happens in the Composition Root — the app target (or a dedicated
CompositionRootmodule). Feature modules never create their own dependencies. - Tests drive the design — one test class per use case, named by behavior (
CacheFeedUseCaseTests, notLocalFeedLoaderTests). UsemakeSUT()factory in every test class. 6b. Test only the public API — no@testable import. Test targets use a plainimport Feed, never@testable import Feed. Tests exercise a module exclusively through its public surface; they never reach forinternal/privatemembers. If a behavior can't be observed publicly, that's a design signal — expose it through the module's public API (a protocol boundary, a return value, an injected collaborator/spy), not by widening access for the test. Same-target tests (e.g. acceptance tests in the app target) still assert through the composed public seams, not private state. - Use SPM multi-target packages for module separation —
Feed(Foundation),FeediOS(UIKit),App(composition). - Prefer async/await over closures/Combine for async operations. Use
Task.immediatefor synchronous-first execution in adapters. - Write new tests in the project's test framework. The reference patterns here are XCTest, as in the source codebase. When the project uses Swift Testing, translate via the
swift-testing-expertskill — notetrackForMemoryLeaks/addTeardownBlockis XCTest-only. - Mark shared mutable state with
@MainActor— presenters, adapters, view controllers, and composition code run on the main actor.