From e1feeb460c8006a641900127468ef4022ac4658b Mon Sep 17 00:00:00 2001 From: Daniel Bernal Date: Mon, 6 Dec 2021 02:38:09 +0100 Subject: [PATCH] Inject custom instance of the JSONDecoder from the WKRequest Allows using a custom instance of the Decoder to be used in each request --- Sources/WireKit/Protocols/WKRequest.swift | 1 + Sources/WireKit/WKAPIClient.swift | 4 ++-- Sources/WireKit/WKNetworkDispatcher.swift | 9 ++++++--- docs/wkrequest.md | 2 ++ 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Sources/WireKit/Protocols/WKRequest.swift b/Sources/WireKit/Protocols/WKRequest.swift index bfd10bf..49bf2b5 100644 --- a/Sources/WireKit/Protocols/WKRequest.swift +++ b/Sources/WireKit/Protocols/WKRequest.swift @@ -37,6 +37,7 @@ public protocol WKRequest { var queryParams: WKHTTPParams? { get } var body: WKHTTPParams? { get } var headers: WKHTTPHeaders? { get } + var decoder: JSONDecoder? { get } } public extension WKRequest { diff --git a/Sources/WireKit/WKAPIClient.swift b/Sources/WireKit/WKAPIClient.swift index 6389fa8..bf28ce4 100644 --- a/Sources/WireKit/WKAPIClient.swift +++ b/Sources/WireKit/WKAPIClient.swift @@ -26,10 +26,10 @@ public struct WKAPIClient { public func dispatch(_ request: Request) -> AnyPublisher { guard let urlRequest = request.asURLRequest(baseURL: baseURL) else { return Fail(outputType: Request.ReturnType.self, failure: WKNetworkRequestError.badRequest).eraseToAnyPublisher() - } + typealias RequestPublisher = AnyPublisher - let requestPublisher: RequestPublisher = networkDispatcher.dispatch(request: urlRequest) + let requestPublisher: RequestPublisher = networkDispatcher.dispatch(request: urlRequest, decoder: request.decoder) return requestPublisher.eraseToAnyPublisher() } } diff --git a/Sources/WireKit/WKNetworkDispatcher.swift b/Sources/WireKit/WKNetworkDispatcher.swift index 888808c..5577c7c 100644 --- a/Sources/WireKit/WKNetworkDispatcher.swift +++ b/Sources/WireKit/WKNetworkDispatcher.swift @@ -34,8 +34,10 @@ public struct WKNetworkDispatcher { /// Dispatches an URLRequest and returns a publisher /// - Parameter request: URLRequest /// - Returns: A publisher with the provided decoded data or an error - public func dispatch(request: URLRequest) -> AnyPublisher { - + public func dispatch(request: URLRequest, decoder: JSONDecoder?) -> AnyPublisher { + + let decoder = decoder ?? JSONDecoder() + return urlSession .dataTaskPublisher(for: request) .tryMap({ data, response in @@ -45,7 +47,7 @@ public struct WKNetworkDispatcher { } return data }) - .decode(type: ReturnType.self, decoder: JSONDecoder()) + .decode(type: ReturnType.self, decoder: decoder) .mapError { error in handleError(error) } @@ -74,6 +76,7 @@ public struct WKNetworkDispatcher { /// - Parameter error: URLSession publisher error /// - Returns: Readable NWKNetworkRequestError private func handleError(_ error: Error) -> WKNetworkRequestError { + print(error) switch error { case is Swift.DecodingError: return .decodingError diff --git a/docs/wkrequest.md b/docs/wkrequest.md index 9801245..d99f8c7 100644 --- a/docs/wkrequest.md +++ b/docs/wkrequest.md @@ -23,3 +23,5 @@ All your API requests should go through `WKRequest`. Here's the parameter list. ### Headers `[String: String]` - Dictionary of headers to be sent. By default Wirekit automatically adds `Content-Type` and `Accept` headers so you don't have to manually addd them here. +### Decoder +`JSONDecoder` - Custom instance of JSONDecoder to be used then decoding this particular request. This is useful to implement custom decoding strategies \ No newline at end of file