diff --git a/Sources/Get/DataLoader.swift b/Sources/Get/DataLoader.swift index 9bfcc45..f221dc4 100644 --- a/Sources/Get/DataLoader.swift +++ b/Sources/Get/DataLoader.swift @@ -312,6 +312,8 @@ private final class DownloadTaskHandler: TaskHandler { // MARK: - Helpers +protocol OptionalDecoding {} + struct DataLoaderError: Error { let task: URLSessionTask let error: Error @@ -333,6 +335,8 @@ extension OperationQueue { } } +extension Optional: OptionalDecoding {} + func encode(_ value: Encodable, using encoder: JSONEncoder) async throws -> Data? { if let data = value as? Data { return data @@ -346,7 +350,9 @@ func encode(_ value: Encodable, using encoder: JSONEncoder) async throws -> Data } func decode(_ data: Data, using decoder: JSONDecoder) async throws -> T { - if T.self == Data.self { + if data.isEmpty, T.self is OptionalDecoding.Type { + return Optional.none as! T + } else if T.self == Data.self { return data as! T } else if T.self == String.self { guard let string = String(data: data, encoding: .utf8) else { @@ -359,3 +365,7 @@ func decode(_ data: Data, using decoder: JSONDecoder) async throws }.value } } + + + + diff --git a/Tests/GetTests/ClientSendingRequestsTests.swift b/Tests/GetTests/ClientSendingRequestsTests.swift index d198f06..9ba177f 100644 --- a/Tests/GetTests/ClientSendingRequestsTests.swift +++ b/Tests/GetTests/ClientSendingRequestsTests.swift @@ -141,7 +141,7 @@ final class ClientSendingRequestsTests: XCTestCase { // THEN returns decoded JSON XCTAssertEqual(user?.login, "kean") } - + // func value(for:) -> Decodable func testResponseEmpty() async throws { // GIVEN @@ -153,6 +153,20 @@ final class ClientSendingRequestsTests: XCTestCase { // WHEN try await client.send(Request(path: "/user")).value } + + func testResponseEmptyWithDecodableOptional() async throws { + // GIVEN + let url = URL(string: "https://api.github.com/user")! + Mock(url: url, dataType: .json, statusCode: 204, data: [ + .get: Data() + ]).register() + + // WHEN + let user: User? = try await client.send(Request(path: "/user")).value + + // THEN returns nil response + XCTAssertNil(user) + } // func value(for:) -> Data func testResponseData() async throws { @@ -170,7 +184,7 @@ final class ClientSendingRequestsTests: XCTestCase { } // func value(for:) -> String - func testResponeString() async throws { + func testResponseString() async throws { // GIVEN let url = URL(string: "https://api.github.com/user")! Mock(url: url, dataType: .json, statusCode: 200, data: [