urlSession
The URL session that features should use to make URL requests.
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: { /* ... */ },
// ...
)
}
}