← ClaudeAtlas

swift-dependency-injectionlisted

Design injectable seams so Swift services can be swapped for fakes in tests. Use when a type reaches for `URLSession.shared`, `Date()`, `UUID()`, `random(in:)` or a singleton; when asked "how do I inject CloudKit / network / clock" or "should this be a singleton"; when choosing constructor vs `@Environment` / `EnvironmentKey` vs `@TaskLocal` injection; when writing the `makeApp()` composition root; when evaluating swift-dependencies or Factory. Does NOT choose the test framework or snapshot tooling (swift-testing-baseline) or the target layout that hosts the root (swiftpm-modularization).
wei18/apple-dev-skills · ★ 19 · Web & Frontend · score 78
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. ## Scope Owns how a seam is shaped and injected (protocol / struct witness / environment / task-local) and how a fake is written. Does NOT own the test framework, snapshot tooling, or where shared fake *types* live → `swift-testing-baseline` (`<Project>KitTesting`). ## 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: Continuous