From b445b06182668a403c8428ad01e78a79439fc289 Mon Sep 17 00:00:00 2001 From: Dominika Gajdova Date: Mon, 3 Feb 2025 14:48:10 +0100 Subject: [PATCH] chore: expose response provider --- .../xcshareddata/swiftpm/Package.resolved | 18 +++++++++++++++++ Sources/Networking/Core/APIManager.swift | 20 +++++++++++++++---- Sources/Networking/Core/APIManaging.swift | 8 +++++++- .../Networking/Core/ResponseProviding.swift | 11 ++++++++++ .../Core/StoredResponseProvider.swift | 2 ++ 5 files changed, 54 insertions(+), 5 deletions(-) diff --git a/Networking.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Networking.xcworkspace/xcshareddata/swiftpm/Package.resolved index 63931882..b20b4929 100644 --- a/Networking.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Networking.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -36,6 +36,24 @@ "version" : "1.2.3" } }, + { + "identity" : "swift-docc-plugin", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-docc-plugin", + "state" : { + "revision" : "85e4bb4e1cd62cec64a4b8e769dcefdf0c5b9d64", + "version" : "1.4.3" + } + }, + { + "identity" : "swift-docc-symbolkit", + "kind" : "remoteSourceControl", + "location" : "https://github.com/swiftlang/swift-docc-symbolkit", + "state" : { + "revision" : "b45d1f2ed151d057b54504d653e0da5552844e34", + "version" : "1.0.0" + } + }, { "identity" : "swift-syntax", "kind" : "remoteSourceControl", diff --git a/Sources/Networking/Core/APIManager.swift b/Sources/Networking/Core/APIManager.swift index 6b1b7d79..1b90ad7f 100644 --- a/Sources/Networking/Core/APIManager.swift +++ b/Sources/Networking/Core/APIManager.swift @@ -49,11 +49,11 @@ open class APIManager: APIManaging, Retryable { private let requestAdapters: [RequestAdapting] private let responseProcessors: [ResponseProcessing] private let errorProcessors: [ErrorProcessing] - private let responseProvider: ResponseProviding private let sessionId: String + private var _responseProvider: ResponseProviding internal var retryCounter = Counter() - + public init( urlSession: URLSession = .init(configuration: .default), requestAdapters: [RequestAdapting] = [], @@ -69,7 +69,7 @@ open class APIManager: APIManaging, Retryable { sessionId = Date().ISO8601Format() } - self.responseProvider = urlSession + self._responseProvider = urlSession self.requestAdapters = requestAdapters self.responseProcessors = responseProcessors self.errorProcessors = errorProcessors @@ -89,7 +89,7 @@ open class APIManager: APIManaging, Retryable { } else { sessionId = Date().ISO8601Format() } - self.responseProvider = responseProvider + self._responseProvider = responseProvider self.requestAdapters = requestAdapters self.responseProcessors = responseProcessors self.errorProcessors = errorProcessors @@ -103,6 +103,18 @@ open class APIManager: APIManaging, Retryable { } } +// MARK: Response provider + +public extension APIManager { + var responseProvider: ResponseProviding { + _responseProvider + } + + func setResponseProvider(_ provider: ResponseProviding) { + self._responseProvider = provider + } +} + private extension APIManager { func request(_ endpointRequest: EndpointRequest, retryConfiguration: RetryConfiguration?) async throws -> Response { do { diff --git a/Sources/Networking/Core/APIManaging.swift b/Sources/Networking/Core/APIManaging.swift index 96971a6f..aa4e5d34 100644 --- a/Sources/Networking/Core/APIManaging.swift +++ b/Sources/Networking/Core/APIManaging.swift @@ -14,7 +14,7 @@ import Foundation public protocol APIManaging { /// A default `JSONDecoder` used for all requests. var defaultDecoder: JSONDecoder { get } - + /// Creates a network request for an API endpoint defined by ``Requestable``. /// - Parameters: /// - endpoint: API endpoint requestable definition. @@ -34,6 +34,12 @@ public protocol APIManaging { decoder: JSONDecoder, retryConfiguration: RetryConfiguration? ) async throws -> DecodableResponse + + /// Invalidates and response provider to gracefully clear out all its tasks. + var responseProvider: ResponseProviding { get } + + /// Replaces the response provider instance used by APIManager. + func setResponseProvider(_ provider: ResponseProviding) } // MARK: - Provide request with default json decoder, retry configuration diff --git a/Sources/Networking/Core/ResponseProviding.swift b/Sources/Networking/Core/ResponseProviding.swift index f6a374bb..d4adf06f 100644 --- a/Sources/Networking/Core/ResponseProviding.swift +++ b/Sources/Networking/Core/ResponseProviding.swift @@ -13,6 +13,9 @@ import Foundation public protocol ResponseProviding { /// Creates a ``Response`` for a given `URLRequest`. func response(for request: URLRequest) async throws -> Response + + /// Invalidates and response provider to gracefully clear out all its tasks. + func invalidate() async } extension URLSession: ResponseProviding { @@ -20,4 +23,12 @@ extension URLSession: ResponseProviding { public func response(for request: URLRequest) async throws -> Response { try await data(for: request) } + + /// Invalidates and response provider to gracefully clear out all its tasks. + /// Warning: URLSession can no longer be used after it's been invalidated and any usage + /// will lead to a crash. + public func invalidate() async { + await allTasks.forEach { $0.cancel() } + invalidateAndCancel() + } } diff --git a/Sources/Networking/Core/StoredResponseProvider.swift b/Sources/Networking/Core/StoredResponseProvider.swift index e4b996d9..13017cc6 100644 --- a/Sources/Networking/Core/StoredResponseProvider.swift +++ b/Sources/Networking/Core/StoredResponseProvider.swift @@ -30,6 +30,8 @@ open class StoredResponseProvider: ResponseProviding { self.sessionId = sessionId } + public func invalidate() async {} + /// Creates a ``Response`` for a given `URLRequest` based on data from a corresponding file stored in Assets. /// - Parameter request: URL request. public func response(for request: URLRequest) async throws -> Response {