Skip to content

Instantly share code, notes, and snippets.

@robertmryan
Created April 28, 2024 16:37
Show Gist options
  • Save robertmryan/8bea4bac0dc8aa6dbfb70f17521ecf1c to your computer and use it in GitHub Desktop.
Save robertmryan/8bea4bac0dc8aa6dbfb70f17521ecf1c to your computer and use it in GitHub Desktop.
func fetchData<M: Decodable>(target: T, responseClass: M.Type = M.self, completion: @escaping(Result<M, Error>) -> Void) {
let method = Alamofire.HTTPMethod(rawValue: target.methods.rawValue)
let headers = Alamofire.HTTPHeaders(target.headers ?? [:])
let params = buildParams(task: target.task)
AF.request(target.baseUrl + target.path, method: method, parameters: params.0, encoding: params.1, headers: headers)
.validate()
.responseDecodable(of: M.self) { response in
switch response.result {
case .success(let value): completion(.success(value))
case .failure(let error): completion(.failure(error))
}
}
}
@robertmryan
Copy link
Author

Three observations:

  1. No need to re-encode and re-decode. Just look at response.result.
  2. As a minor refinement, made responseClass an optional parameter (as often the type can be inferred from the context). But I kept the parameter for those cases where the compiler cannot infer the type automatically).
  3. I also used validate to check the status code for you.

@robertmryan
Copy link
Author

Also note, in the process of simplifying this, I have retired the use of try?, which throws away any meaningful diagnostic information. Always pass along the meaningful error. If the caller doesn't care about the details, it can disregard the error’s details if it wants. But in those cases where you actually have parsing errors, it is exceptionally useful to have the details (so you know which field(s) caused the problem).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment