Last active
February 21, 2022 01:56
-
-
Save hlung/b292467c1488e5cbf121131f54c25dee to your computer and use it in GitHub Desktop.
APIClient startDecodableRequest
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Foundation | |
class APIClient { | |
// 1 - Error enum | |
enum APIClientError: Error { | |
case dataTaskFailed(Error) | |
case noHTTPURLResponse | |
case badHTTPStatusCode(HTTPURLResponse) | |
case noData | |
case decodingFailed(Error) | |
case unknown(Error) | |
} | |
let session = URLSession.shared | |
func startDecodableRequest<T: Decodable>( | |
_ request: URLRequest, | |
decoder: JSONDecoder = JSONDecoder(), | |
completionQueue: DispatchQueue = DispatchQueue.main, | |
completion: @escaping ((Result<T, APIClientError>) -> Void) | |
) { | |
let task = session.dataTask(with: request, | |
completionHandler: { data, response, error in | |
do { | |
// 2 - Check error and status code | |
if let error = error { | |
throw APIClientError.dataTaskFailed(error) | |
} | |
guard let urlResponse = response as? HTTPURLResponse else { | |
throw APIClientError.noHTTPURLResponse | |
} | |
let validStatusCodes = 200...399 | |
guard validStatusCodes.contains(urlResponse.statusCode) else { | |
throw APIClientError.badHTTPStatusCode(urlResponse) | |
} | |
// 3 - Decode data | |
guard let data = data else { | |
throw APIClientError.noData | |
} | |
let decoded: T | |
do { | |
decoded = try decoder.decode(T.self, from: data) | |
} | |
catch { | |
throw APIClientError.decodingFailed(error) | |
} | |
// 4 - Call completion for success | |
completionQueue.async { | |
completion(.success(decoded)) | |
} | |
} | |
catch { | |
// 5 - Call completion for failure | |
let finalError = error as? APIClientError ?? .unknown(error) | |
completionQueue.async { | |
completion(.failure(finalError)) | |
} | |
} | |
}) | |
task.resume() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment