Skip to main content

Overview

The @Dependency property wrapper allows you to access dependencies from anywhere in your reducer. Dependencies are external systems your features need to interact with, such as API clients, date generators, UUID generators, clocks, and more. This property wrapper is provided by the swift-dependencies library, which is integrated into The Composable Architecture.

Why Use Dependencies?

Controlling dependencies provides several benefits:
  • Testability: Replace real implementations with mocks in tests
  • Previews: Provide fake data for SwiftUI previews
  • Determinism: Control random or time-based values for consistent behavior
  • Separation of concerns: Keep feature logic separate from implementation details

Basic Usage

Use @Dependency with a key path to access any registered dependency:

Accessing Dependencies in Effects

Dependencies are automatically propagated to effects:

Built-in Dependencies

The Composable Architecture provides several built-in dependencies:

Date and Time

UUID Generation

Clocks

Dismissal

Use in child features to dismiss themselves:

Presentation State

Check if the feature is currently presented:

Creating Custom Dependencies

Define your own dependencies by conforming to DependencyKey:

Testing with Dependencies

Override dependencies in tests using withDependencies:

Overriding Dependencies for Specific Reducers

Override dependencies for a specific reducer and all its children:

Test Dependencies

Provide test-only implementations using testValue:
This causes tests to fail if a dependency is used without being explicitly overridden.

Preview Dependencies

Provide preview data for SwiftUI previews:

Accessing All Dependencies

Access the entire dependency container:
This is useful for passing dependencies to other systems or for debugging.

Best Practices

  1. Define clear interfaces: Keep dependency types focused and interface-oriented
  2. Provide test values: Always define testValue to catch unimplemented dependencies in tests
  3. Use live values for previews: Or provide realistic mock data for a better preview experience
  4. Avoid side effects in init: Don’t perform work when creating dependency values
  5. Make dependencies async when appropriate: Use async for operations that involve waiting

Common Patterns

Optional Dependencies

For dependencies that may not always be available:

Throwing Dependencies

For test dependencies that should fail:

See Also