Una breve classe da cui prendere spunto:
// MARK: - WebServiceError
public enum WebServiceError: Error {
case badURL
case error
case nodata
case jsonError
// ...
}
// MARK: - WebService
public class WebService {
let baseUrl: String
public enum HttpMethod: String {
case GET
case POST
case PUT
case TRACE
case DELETE
}
public init?(baseUrl: String) {
guard !baseUrl.isEmpty else {
return nil
}
if baseUrl.last! == "/" {
self.baseUrl = baseUrl
} else {
self.baseUrl = baseUrl+"/"
}
}
public func request<T>(with httpMethod: HttpMethod = .GET,
of _: T.Type,
on path: String, _ completion: @escaping (Result<T, WebServiceError>) -> Void) -> Void where T: Codable
{
guard let url = URL(string: baseUrl + path) else {
completion(.failure(.badURL))
return
}
var request = URLRequest(url: url)
request.httpMethod = httpMethod.rawValue
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Accept")
let task = URLSession.shared.dataTask(with: request) { data, response, error in
var result: Result<T, WebServiceError>
defer {
completion(result)
}
guard error == nil else {
result = .failure(.error)
return
}
guard let data = data else {
result = .failure(.nodata)
return
}
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
guard let response = try? decoder.decode(T.self, from: data) else {
result = .failure(.jsonError)
return
}
result = .success(response)
}
task.resume()
}
}