From da687d451eab8f3a72cd91318ef5d165e07352aa Mon Sep 17 00:00:00 2001 From: Hishara Dilshan Date: Fri, 27 Dec 2024 10:31:17 +0000 Subject: [PATCH 1/3] Reorder methods --- .../NetworkDataTransferService.swift | 117 +++++++++--------- 1 file changed, 59 insertions(+), 58 deletions(-) diff --git a/Sources/Networking/DataTranserService/NetworkDataTransferService.swift b/Sources/Networking/DataTranserService/NetworkDataTransferService.swift index 5fa0644..05da12a 100644 --- a/Sources/Networking/DataTranserService/NetworkDataTransferService.swift +++ b/Sources/Networking/DataTranserService/NetworkDataTransferService.swift @@ -68,6 +68,35 @@ public final class DefaultNetworkDataTransferService { group.leave() } } + + + private func decode(data: Data?, decoder: ResponseDecoder) -> Result { + do { + guard let data = data else { + return .failure(NetworkDataTransferError.noResponse) + } + + let decoded: T = try decoder.decode(data: data) + return .success(decoded) + } catch { + self.logger.log(error: error) + return .failure(NetworkDataTransferError.parsing(error)) + } + } + + private func decode(data: Data?, decoder: ResponseDecoder) throws -> T { + do { + guard let data = data else { + throw NetworkDataTransferError.noResponse + } + + let decoded: T = try decoder.decode(data: data) + return decoded + } catch { + self.logger.log(error: error) + throw NetworkDataTransferError.parsing(error) + } + } } extension DefaultNetworkDataTransferService: NetworkDataTransferService { @@ -101,6 +130,36 @@ extension DefaultNetworkDataTransferService: NetworkDataTransferService { return requestCollection } + public func request( + with endpoint: E, + on queue: (any NetworkDataTransferQueue)? = nil, + completion: @escaping (Result) -> Void + ) -> (any CancellableHttpRequest)? where E.ResponseType == T { + + return networkService.request(endpoint: endpoint) { result in + let completionResult: Result + + defer { + if let queue = queue { + queue.asyncExecute { + completion(completionResult) + } + } + completion(completionResult) + } + + switch result { + case .success(let data): + let result: Result = self.decode(data: data, decoder: endpoint.responseDecoder) + completionResult = result + case .failure(let error): + self.logger.log(error: error) + completionResult = .failure(.networkFailure(error)) + } + } + + } + @available(macOS 10.15, *) @available(iOS 16, *) public func request(with endpoints: [E]) async -> TaskTypeCollection where T == E.ResponseType { @@ -140,62 +199,4 @@ extension DefaultNetworkDataTransferService: NetworkDataTransferService { return task } - - public func request( - with endpoint: E, - on queue: (any NetworkDataTransferQueue)? = nil, - completion: @escaping (Result) -> Void - ) -> (any CancellableHttpRequest)? where E.ResponseType == T { - - return networkService.request(endpoint: endpoint) { result in - let completionResult: Result - - defer { - if let queue = queue { - queue.asyncExecute { - completion(completionResult) - } - } - completion(completionResult) - } - - switch result { - case .success(let data): - let result: Result = self.decode(data: data, decoder: endpoint.responseDecoder) - completionResult = result - case .failure(let error): - self.logger.log(error: error) - completionResult = .failure(.networkFailure(error)) - } - } - - } - - private func decode(data: Data?, decoder: ResponseDecoder) -> Result { - do { - guard let data = data else { - return .failure(NetworkDataTransferError.noResponse) - } - - let decoded: T = try decoder.decode(data: data) - return .success(decoded) - } catch { - self.logger.log(error: error) - return .failure(NetworkDataTransferError.parsing(error)) - } - } - - private func decode(data: Data?, decoder: ResponseDecoder) throws -> T { - do { - guard let data = data else { - throw NetworkDataTransferError.noResponse - } - - let decoded: T = try decoder.decode(data: data) - return decoded - } catch { - self.logger.log(error: error) - throw NetworkDataTransferError.parsing(error) - } - } } From 60dbb9ad3aafa576985b8ddaebc7568db6bb0dcd Mon Sep 17 00:00:00 2001 From: Hishara Dilshan Date: Fri, 27 Dec 2024 10:35:30 +0000 Subject: [PATCH 2/3] Added async methods to return Generic Decodable Types --- .../NetworkDataTransferService.swift | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/Sources/Networking/DataTranserService/NetworkDataTransferService.swift b/Sources/Networking/DataTranserService/NetworkDataTransferService.swift index 05da12a..a6d164f 100644 --- a/Sources/Networking/DataTranserService/NetworkDataTransferService.swift +++ b/Sources/Networking/DataTranserService/NetworkDataTransferService.swift @@ -31,9 +31,17 @@ public protocol NetworkDataTransferService: AnyObject { @available(iOS 16, *) func request(with endpoint: E) async -> TaskType where E.ResponseType == T + @available(macOS 10.15, *) + @available(iOS 16, *) + func request(with endpoint: E) async throws -> T where E.ResponseType == T + @available(iOS 16, *) @available(macOS 10.15, *) func request(with endpoints: [E]) async -> TaskTypeCollection where E.ResponseType == T + + @available(iOS 16, *) + @available(macOS 10.15, *) + func request(with endpoints: [E]) async throws -> [T] where E.ResponseType == T } // MARK: Concrete Implementation @@ -187,6 +195,28 @@ extension DefaultNetworkDataTransferService: NetworkDataTransferService { return task } + @available(macOS 10.15, *) + @available(iOS 16, *) + public func request(with endpoints: [E]) async throws -> [T] where T == E.ResponseType { + let responseData = try await withThrowingTaskGroup(of: T.self, returning: [T].self) { taskGroup in + for endpoint in endpoints { + taskGroup.addTask { + try await self.request(with: endpoint).value + } + } + + var data: [T] = [] + + for try await item in taskGroup { + data.append(item) + } + + return data + } + + return responseData + } + @available(macOS 10.15, *) @available(iOS 16, *) public func request(with endpoint: E) async -> TaskType where T == E.ResponseType { @@ -199,4 +229,13 @@ extension DefaultNetworkDataTransferService: NetworkDataTransferService { return task } + + @available(macOS 10.15, *) + @available(iOS 16, *) + public func request(with endpoint: E) async throws -> T where T == E.ResponseType { + let responseData = try await networkService.request(endpoint: endpoint).value + let decodedData:T = try self.decode(data: responseData, decoder: endpoint.responseDecoder) + + return decodedData + } } From cb6f22ef5e060547c9aa9d46379ffd5ff969583c Mon Sep 17 00:00:00 2001 From: Hishara Dilshan Date: Fri, 27 Dec 2024 10:47:05 +0000 Subject: [PATCH 3/3] Updated tests to fix ambiguous types --- Tests/NetworkingTests/Network+DataTransferTests.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/NetworkingTests/Network+DataTransferTests.swift b/Tests/NetworkingTests/Network+DataTransferTests.swift index 21f37a1..9d48e92 100644 --- a/Tests/NetworkingTests/Network+DataTransferTests.swift +++ b/Tests/NetworkingTests/Network+DataTransferTests.swift @@ -132,7 +132,7 @@ final class NetworkingTests: XCTestCase { let index = 9 let key: KeyPath = \.name - let task = await networkDataTransferService.request(with: testEndpoints) + let task: Task<[ResponseObject], Error> = await networkDataTransferService.request(with: testEndpoints) testEndpoints.forEach { endpoint in print("=======Endpoint \(endpoint.path)=======") @@ -152,7 +152,7 @@ final class NetworkingTests: XCTestCase { @available(iOS 16, *) func test_async_service_returns_result() async { let expectedCount = 10 - let task = await networkDataTransferService.request(with: endpoint) + let task: Task<[ResponseObject], Error> = await networkDataTransferService.request(with: endpoint) do { let items: [ResponseObject] = try await task.value