Skip to content

Instantly share code, notes, and snippets.

@hassanvfx
Created January 29, 2024 15:18
Show Gist options
  • Save hassanvfx/6c90a02def019de41cf1a9a2da5fb11a to your computer and use it in GitHub Desktop.
Save hassanvfx/6c90a02def019de41cf1a9a2da5fb11a to your computer and use it in GitHub Desktop.
Generic URLSession call
// Generic function to fetch and decode JSON into a Codable object
func fetchDecodedObject<T: Codable>(from urlString: String, completion: @escaping (Result<T, NetworkError>) -> Void) {
// Step 1: Create a URL instance
guard let url = URL(string: urlString) else {
completion(.failure(.badURL))
return
}
// Step 2: Create a URLSession
let session = URLSession.shared
// Step 3: Create a URLSessionDataTask
let task = session.dataTask(with: url) { (data, response, error) in
// Step 4: Handle the Data, Response, and Error
if let error = error {
completion(.failure(.requestFailed(error)))
return
}
guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
completion(.failure(.badStatusCode((response as? HTTPURLResponse)?.statusCode ?? -1)))
return
}
guard let data = data else {
completion(.failure(.requestFailed(error!)))
return
}
// Decode the JSON data into the generic type T
do {
let decodedObject = try JSONDecoder().decode(T.self, from: data)
completion(.success(decodedObject))
} catch let decodingError {
completion(.failure(.decodingFailed(decodingError)))
}
}
// Start the task
task.resume()
}
struct MyModel: Codable {
var property1: String
var property2: Int
// ... other properties
}
enum NetworkError: Error {
case badURL
case requestFailed(Error)
case badStatusCode(Int)
case decodingFailed(Error)
}
fetchDecodedObject(from: "https://api.example.com/endpoint") { (result: Result<MyModel, NetworkError>) in
switch result {
case .success(let model):
print(model)
case .failure(let error):
print("Error: \(error)")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment