urlSession

The URL session that features should use to make URL requests.

URLSession.swift:79
var urlSession: URLSession { get set }

By default, the session returned from URLSession.shared is supplied. When used in tests, access will call to reportIssue when invoked, unless explicitly overridden:

// Provision model with overridden dependencies
let model = withDependencies {
  let mockConfiguration = URLSessionConfiguration.ephemeral
  mockConfiguration.protocolClasses = [MyMockURLProtocol.self]
  $0.urlSession = URLSession(configuration: mockConfiguration)
} operation: {
  FeatureModel()
}

// Make assertions with model...

API client dependencies

While it is possible to use this dependency value from more complex dependencies, like API clients, we generally advise against designing a dependency around a URL session. Mocking a URL session’s responses is a complex process that requires a lot of work that can be avoided.

For example, instead of defining your dependency in a way that holds directly onto a URL session in order to invoke it from a concrete implementation:

struct APIClient {
  let urlSession: URLSession

  func fetchProfile() async throws -> Profile {
    // Use URL session to make request
  }

  func fetchTimeline() async throws -> Timeline { /* ... */ }
  // ...
}

Define your dependency as a lightweight interface that holds onto endpoints that can be individually overridden in a lightweight fashion:

struct APIClient {
  var fetchProfile: () async throws -> Profile
  var fetchTimeline: () async throws -> Timeline
  // ...
}

Then, you can extend this type with a live implementation that uses a URL session under the hood:

extension APIClient: DependencyKey {
  static var liveValue: APIClient {
    @Dependency(\.urlSession) var urlSession

    return Self(
      fetchProfile: {
        // Use URL session to make request
      }
      fetchTimeline: { /* ... */ },
      // ...
    )
  }
}