From 0ff6634c2099550aaae582ec9277d19ea3434eca Mon Sep 17 00:00:00 2001 From: mino Date: Thu, 30 Nov 2023 10:20:34 +0900 Subject: [PATCH 1/7] chore: rename --- Sources/CuteNetwork/FormParameterEncoder.swift | 4 ++-- Sources/CuteNetwork/ParameterEncoding.swift | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/CuteNetwork/FormParameterEncoder.swift b/Sources/CuteNetwork/FormParameterEncoder.swift index aa449f3..d9f96dd 100644 --- a/Sources/CuteNetwork/FormParameterEncoder.swift +++ b/Sources/CuteNetwork/FormParameterEncoder.swift @@ -1,5 +1,5 @@ // -// FORMParameterEncoder.swift +// FormarameterEncoder.swift // // // Created by mino on 2023/11/29. @@ -7,7 +7,7 @@ import Foundation -public struct FORMParameterEncoder: ParameterEncoder { +public struct FormParameterEncoder: ParameterEncoder { public func encode(urlRequest: inout URLRequest, with parameters: Parameters) throws { var parameterArray = [String]() for param in parameters { diff --git a/Sources/CuteNetwork/ParameterEncoding.swift b/Sources/CuteNetwork/ParameterEncoding.swift index db3e4f9..b3cd3a7 100644 --- a/Sources/CuteNetwork/ParameterEncoding.swift +++ b/Sources/CuteNetwork/ParameterEncoding.swift @@ -35,7 +35,7 @@ public enum ParameterEncoding { case .formEncoding: guard let bodyParameters = bodyParameters else { return } - try FORMParameterEncoder().encode(urlRequest: &urlRequest, with: bodyParameters) + try FormParameterEncoder().encode(urlRequest: &urlRequest, with: bodyParameters) } } catch { throw error From 952d21431a79db4453dae81a11e71bc43d40eb88 Mon Sep 17 00:00:00 2001 From: mino Date: Thu, 30 Nov 2023 10:22:57 +0900 Subject: [PATCH 2/7] feat: Add Encodable extension(object to parameter) --- Sources/CuteNetwork/Encodable+parameter.swift | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 Sources/CuteNetwork/Encodable+parameter.swift diff --git a/Sources/CuteNetwork/Encodable+parameter.swift b/Sources/CuteNetwork/Encodable+parameter.swift new file mode 100644 index 0000000..119bb72 --- /dev/null +++ b/Sources/CuteNetwork/Encodable+parameter.swift @@ -0,0 +1,17 @@ +// +// Encodable+parameter.swift +// +// +// Created by DEV IOS on 2023/11/30. +// + +import Foundation + +extension Encodable { + var toParameter: [String: Any]? { + guard let object = try? JSONEncoder().encode(self) else { return nil } + guard let dictionary = try? JSONSerialization.jsonObject(with: object, options: []) + as? [String: Any] else { return nil } + return dictionary + } +} From 18029806ef2bda1e994034ba1beed501a23bf5b2 Mon Sep 17 00:00:00 2001 From: mino Date: Thu, 30 Nov 2023 10:23:26 +0900 Subject: [PATCH 3/7] =?UTF-8?q?chore:=20error=20handling=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/CuteNetwork/Cute.swift | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/Sources/CuteNetwork/Cute.swift b/Sources/CuteNetwork/Cute.swift index ed09fd5..5d4828e 100644 --- a/Sources/CuteNetwork/Cute.swift +++ b/Sources/CuteNetwork/Cute.swift @@ -11,14 +11,19 @@ class Cute: NSObject, NetworkRouter, URLSessionDelegate /// Properties private var task: URLSessionTask? /// petit(_ root: EndPoint, petitLogVisible: Bool) async throws -> Data 함수를 통해 받은 Data를 파싱해주는 함수입니다. - func petit(_ root: EndPoint, petitLogVisible: Bool = true) async throws -> T{ - let result = try await petit(root, petitLogVisible: petitLogVisible) + func petit(_ root: EndPoint, petitLogVisible: Bool = true) async throws -> T { do { + let result = try await petit(root, petitLogVisible: petitLogVisible) + let decoder = JSONDecoder() let data = try decoder.decode(T.self, from: result) + return data } catch { - throw NetworkError.parsingError + /// [1] `result` error handling + if let networkError = error as? NetworkError { throw networkError } + /// [2] `Decode fail` error handling + else { throw NetworkError.parsingError } } } /// petit(_ route: EndPoint, logAccess: Bool, completion: @escaping NetworkRouterCompletion)를 받아 From 8599f30f67d5b6c2132e97c93ca4f6bff9963081 Mon Sep 17 00:00:00 2001 From: mino Date: Thu, 30 Nov 2023 10:23:36 +0900 Subject: [PATCH 4/7] feat: test - mock --- Tests/CuteNetworkTests/CuteNetworkTests.swift | 36 +++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/Tests/CuteNetworkTests/CuteNetworkTests.swift b/Tests/CuteNetworkTests/CuteNetworkTests.swift index 911c604..30e8b8a 100644 --- a/Tests/CuteNetworkTests/CuteNetworkTests.swift +++ b/Tests/CuteNetworkTests/CuteNetworkTests.swift @@ -2,10 +2,42 @@ import XCTest @testable import CuteNetwork final class CuteNetworkTests: XCTestCase { - func testExample() throws { + enum MockEndpoint: EndPointType { + case test + + var baseURL: URL { + return URL(string: "123")! + } + + var path: String { + return "" + } + + var httpMethod: CuteNetwork.HTTPMethod { + return .get + } + + var task: CuteNetwork.HTTPTask { + return .request + } + + var headers: CuteNetwork.HTTPHeaders? { + return [:] + } + } + + + func testExample() async throws { + + let cute = Cute() + do { + let a = try await cute.petit(.test, petitLogVisible: false) +// XCTAssertNotEqual(a, Data()) + } catch { + print("error: \(error)") + } // This is an example of a functional test case. // Use XCTAssert and related functions to verify your tests produce the correct // results. - XCTAssertEqual(CuteNetwork().text, "Hello, World!") } } From 499bc5d6ffe5ac067d5ca7b344d5fcd3473dc109 Mon Sep 17 00:00:00 2001 From: mino Date: Thu, 30 Nov 2023 10:41:42 +0900 Subject: [PATCH 5/7] =?UTF-8?q?chore:=20log=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/CuteNetwork/NetworkLogger.swift | 32 ++++++++++++------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/Sources/CuteNetwork/NetworkLogger.swift b/Sources/CuteNetwork/NetworkLogger.swift index 9576f0b..0ce1da1 100644 --- a/Sources/CuteNetwork/NetworkLogger.swift +++ b/Sources/CuteNetwork/NetworkLogger.swift @@ -11,9 +11,6 @@ class NetworkLogger { static func log(request: URLRequest) { - debugPrint("🥚 [NetworkLogger Start]") - defer { debugPrint("🐥 [NetworkLogger End]") } - let urlAsString = request.url?.absoluteString ?? "" let urlComponents = NSURLComponents(string: urlAsString) @@ -21,27 +18,30 @@ class NetworkLogger { let path = "\(urlComponents?.path ?? "")" let query = "\(urlComponents?.query ?? "")" let host = "\(urlComponents?.host ?? "")" - debugPrint("🐣 [NetworkLogger Request] URL: \(urlAsString)\n") - debugPrint("🐣 [NetworkLogger Request] Method: \(method)") - debugPrint("🐣 [NetworkLogger Request] Path: \(path)") - debugPrint("🐣 [NetworkLogger Request] query: \(query)") - var logOutput = """ - \(urlAsString) \n\n - \(method) \(path)?\(query) HTTP/1.1 \n - HOST: \(host)\n - """ var bodyLog: String = "" - - for (key, value) in request.allHTTPHeaderFields ?? [:] { - logOutput += "\(key): \(value) \n" - } + + let headerLog = (request.allHTTPHeaderFields ?? [:]) + .map { "\($0.key): \($0.value)" } + .joined(separator: "\n") + if let body = request.httpBody { bodyLog += "\n \(NSString(data: body, encoding: String.Encoding.utf8.rawValue) ?? "")" } + debugPrint("🥚 [NetworkLogger Start]") + defer { debugPrint("🐥 [NetworkLogger End]") } + debugPrint("🐣 [NetworkLogger Request] URL: \(urlAsString)\n") + debugPrint("🐣 [NetworkLogger Request] Method: \(method)") + debugPrint("🐣 [NetworkLogger Request] Path: \(path)") + debugPrint("🐣 [NetworkLogger Request] query: \(query)") + #if DEBUG /// debugPrint는 멀티라인을 지원하지 않기 때문에 print로 사용하고 debug처리 + print(""" + "🐣 [NetworkLogger Header] header:\n \(headerLog)"\n + """) + print(""" "🐣 [NetworkLogger Request] body:\n \(bodyLog)"\n """) From 6c58b3b4bc525163534c49ed53b0ddd9234386d4 Mon Sep 17 00:00:00 2001 From: mino Date: Thu, 30 Nov 2023 10:43:02 +0900 Subject: [PATCH 6/7] chore: Modify map to forEach --- Sources/CuteNetwork/Cute.swift | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/Sources/CuteNetwork/Cute.swift b/Sources/CuteNetwork/Cute.swift index 5d4828e..ffe8594 100644 --- a/Sources/CuteNetwork/Cute.swift +++ b/Sources/CuteNetwork/Cute.swift @@ -121,11 +121,6 @@ fileprivate extension Cute { func addHeaders(_ headers: HTTPHeaders?, request: inout URLRequest) { guard let headers = headers else { return } - - let _ = headers.map { request.setValue($0, forHTTPHeaderField: $1) } - -// for (key, value) in headers { -// request.setValue(value, forHTTPHeaderField: key) -// } + headers.forEach { request.setValue($0, forHTTPHeaderField: $1) } } } From d1082cce876c775c9941ea5e80c378741a96a4d2 Mon Sep 17 00:00:00 2001 From: mino Date: Thu, 30 Nov 2023 11:15:10 +0900 Subject: [PATCH 7/7] =?UTF-8?q?chore:=20resume=20=EB=82=B4=EB=B6=80=20?= =?UTF-8?q?=EB=B6=84=EA=B8=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sources/CuteNetwork/Cute.swift | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/Sources/CuteNetwork/Cute.swift b/Sources/CuteNetwork/Cute.swift index ffe8594..7d8f73a 100644 --- a/Sources/CuteNetwork/Cute.swift +++ b/Sources/CuteNetwork/Cute.swift @@ -32,13 +32,25 @@ class Cute: NSObject, NetworkRouter, URLSessionDelegate return try await withCheckedThrowingContinuation({ value in petit(root, logAccess: petitLogVisible) { data, response, error in if let error { - value.resume(throwing: error) - } else if let data { - value.resume(returning: data) - } else { - value.resume(throwing: NetworkError.noData) + value.resume(throwing: error as? NetworkError ?? NetworkError.custom(message: error.localizedDescription)) } + if let response = response as? HTTPURLResponse { + let result = ResponseHandler.handleNetworkResponse(response) + switch result { + case .success: + guard let data else { + value.resume(throwing: NetworkError.custom(message: "데이터를 받지 못했습니다.")) + return + } + value.resume(returning: data) + case .failure(let message): + guard let _ = data else { + value.resume(throwing: NetworkError.custom(message: message)) + return + } + } + } } }) }