← ClaudeAtlas

swift-dependency-injectionlisted

Testable seam design via protocol injection, SwiftUI environment, and task-local overrides; Swift 6 Sendable rules for dependencies; mentions pointfreeco/swift-dependencies and Factory as library options. Invoke when designing a new service seam, asking "how do I inject CloudKit/network/clock", setting up a composition root, or making code testable.
wei18/apple-dev-skills · ★ 0 · AI & Automation · score 70
Install: claude install-skill wei18/apple-dev-skills
# Swift Dependency Injection ## When to invoke - Designing a new service boundary (CloudKit, networking, clock, RNG, notifications). - Asking "how do I make this testable", "how do I inject X", or "should I use a singleton here". - Establishing a composition root for a new app target or module. - Reviewing code that reaches out to global state, `URLSession.shared`, `Date()`, or `UUID()`. - Choosing between constructor injection and SwiftUI environment injection. ## Core principle: one composition root All concrete implementations are wired in a single place — typically `makeApp(...)` or a `DependencyContainer` struct built in the `@main` entry point. Every layer below receives its dependencies through initialiser parameters, not by reaching up to a global. This makes the entire wiring visible in one screen of code and means tests can substitute any dependency without touching production paths. ```swift // App entry point — the only place that knows about live implementations @main struct MyApp: App { let root = makeApp() // returns a pure value/struct carrying live deps var body: some Scene { ... } } func makeApp() -> AppRoot { AppRoot( storage: LiveStorage(), clock: ContinuousClock(), rng: SystemRandomNumberGenerator() ) } ``` No layer below `makeApp` imports `LiveStorage` or any other concrete type. ## Protocol-witness vs protocol-existential Both are idiomatic Swift; the choice is a matter of callsite ergonomics: - **Proto