/
ioser
/
imageFeedTestApp
Обзор
Документация
Войти
/
ioser
/
imageFeedTestApp
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
ImageFeedTestApp/NetworkLayer/NetworkClient.swift
101 строка
3 KB
Sbat2000
[NL] настроил получение результата запроса
09 сен 2024, 15:54
09 сен 2024, 15:54
9ed1262
Код
Авторство
О чём код?
// // NetworkClient.swift // ImageFeedTestApp // // Created by Aleksandr Garipov on 09.09.2024. // import Foundation enum NetworkClientError: Error { case httpStatusCode(Int) case urlRequestError(Error) case urlSessionError case parsingError } protocol NetworkClientProtocol { @discardableResult func send<T: Decodable>(request: NetworkRequest, type: T.Type, onResponse: @escaping (Result<T, Error>) -> Void) -> NetworkTask? } struct DefaultNetworkClient: NetworkClientProtocol { private let session: URLSession private let decoder: JSONDecoder private let encoder: JSONEncoder init(session: URLSession = URLSession.shared, decoder: JSONDecoder = JSONDecoder(), encoder: JSONEncoder = JSONEncoder()) { self.session = session self.decoder = decoder self.encoder = encoder } @discardableResult func send<T: Decodable>(request: NetworkRequest, type: T.Type, onResponse: @escaping (Result<T, Error>) -> Void) -> NetworkTask? { guard let urlRequest = create(request: request) else { return nil } let task = session.dataTask(with: urlRequest) { data, response, error in guard let response = response as? HTTPURLResponse else { onResponse(.failure(NetworkClientError.urlSessionError)) return } guard 200 ..< 300 ~= response.statusCode else { onResponse(.failure(NetworkClientError.httpStatusCode(response.statusCode))) return } if let data = data { self.parse(data: data, type: type, onResponse: onResponse) } else if let error = error { onResponse(.failure(NetworkClientError.urlRequestError(error))) } } task.resume() return DefaultNetworkTask(dataTask: task) } // MARK: - Private private func create(request: NetworkRequest) -> URLRequest? { guard let endpoint = request.endpoint else { assertionFailure("Empty endpoint") return nil } var urlRequest = URLRequest(url: endpoint) urlRequest.httpMethod = request.httpMethod.rawValue if let headers = request.headers { for (key, value) in headers { urlRequest.setValue(value, forHTTPHeaderField: key) } } if let dto = request.dto, let dtoEncoded = try? encoder.encode(dto) { urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type") urlRequest.httpBody = dtoEncoded } return urlRequest } private func parse<T: Decodable>(data: Data, type: T.Type, onResponse: @escaping (Result<T, Error>) -> Void) { do { let decoderResponse = decoder decoderResponse.keyDecodingStrategy = .convertFromSnakeCase decoderResponse.dateDecodingStrategy = .iso8601 let response = try decoderResponse.decode(T.self, from: data) onResponse(.success(response)) } catch { onResponse(.failure(NetworkClientError.parsingError)) } } }