title: iOS create generic Alamofire request using swift
body: <p>Recently I have started learning iOS app development using swift so I am new to it. I want to implement rest api call in swift &amp; found that we can achieve this using <code>URLRequest</code>. So I have written <code>generic method</code> to call all type(like <code>get, put, post</code>) of rest api as below.  </p>
  
  <pre><code>import Foundation
  //import Alamofire
  
  public typealias JSON = [String: Any]
  public typealias HTTPHeaders = [String: String];
  
  public enum RequestMethod: String {
      case get = "GET"
      case post = "POST"
      case put = "PUT"
      case delete = "DELETE"
  }
  public enum Result&lt;Value&gt; {
      case success(Value)
      case failure(Error)
  }
  public class apiClient{
      private  var base_url:String = "https://api.testserver.com/"
      private func apiRequest(endPoint: String,
                              method: RequestMethod,
                              body: JSON? = nil,
                              token: String? = nil,
                              completionHandler: @escaping (Data?, URLResponse?, Error?) -&gt; Void) {
          let url = URL(string: (base_url.self + endPoint))!
          var urlRequest = URLRequest(url: url)
          urlRequest.httpMethod = method.rawValue
          urlRequest.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
          if let token = token {
              urlRequest.setValue("bearer " + token, forHTTPHeaderField: "Authorization")
          }
          if let body = body {
              urlRequest.httpBody = try? JSONSerialization.data(withJSONObject: body)
          }
          let session = URLSession(configuration: .default)
          let task = session.dataTask(with: urlRequest) { data, response, error in
              //NSLog(error)
              completionHandler(data, response, error)
          }
          task.resume()
      }
      public func sendRequest&lt;T: Decodable&gt;(for: T.Type = T.self,
                                            endPoint: String,
                                            method: RequestMethod,
                                            body: JSON? = nil,
                                            token: String? = nil,
                                            completion: @escaping (Result&lt;T&gt;) -&gt; Void) {
          return apiRequest(endPoint: endPoint, method: method, body:body, token: token) { data, response, error in
              guard let data = data else {
                  return completion(.failure(error ?? NSError(domain: "SomeDomain", code: -1, userInfo: nil)))
              }
              do {
                  let decoder = JSONDecoder()
                  try completion(.success(decoder.decode(T.self, from: data)))
              } catch let decodingError {
                  completion(.failure(decodingError))
              }
          }
      }
  }
  </code></pre>
  
  <p>this is how I call it method from <code>controller</code></p>
  
  <pre><code>public func getProfile(userId :Int, objToken:String) -&gt; Void {
          let objApi = apiClient()
          objApi.sendRequest(for: ProfileDetails.self,
                             endPoint:"api/user/profile/\(userId)",
                             method: .get,
                             token: objToken,
              completion:
              {(userResult: Result&lt;ProfileDetails&gt;) -&gt; Void in
                  switch userResult
                  {
                  case .success(let value):
                      if value.respCode == "01" {
                          print(value.profile)
                          do {
                              //... ddo some taks like store response in local db or else
                          } catch let error as NSError {
                              // handle error
                              print(error)
                          }
                      }
                      else {
                          //do some task
                      }
                      break
                  case .failure(let error):
                      print(error)
                      break
                  }
          })
      }
  </code></pre>
  
  <p>I am decoding server response in below model</p>
  
  <pre><code>class ProfileDetails : Response, Decodable {    
      var appUpdate : AppUpdate?
      var profile : Profile?
  
      enum CodingKeys: String, CodingKey {
          case profile = "profile"
          case respCode = "resp_code"
          case respMsg = "resp_msg"
      }
      public required convenience init(from decoder: Decoder) throws {
          self.init()
          let values = try decoder.container(keyedBy: CodingKeys.self)
          self.profile = try values.decodeIfPresent(Profile.self, forKey: .profile)
          self.respCode = try values.decodeIfPresent(String.self, forKey: .respCode)!
          self.respMsg = try values.decodeIfPresent(String.self, forKey: .respMsg)
      }
  }
  </code></pre>
  
  <p>This code is not able to handle error response like <code>401, 404</code> etc from server. So what I am looking for, is to <strong>convert this api (<code>URLRequest</code>)request to generic <code>Alamofire</code> request</strong> with error handling like <code>401, 404</code> etc. I have install <code>Alamofire</code> pods. Is there anyone who has developed generic <code>Alamofire</code> request method with <strong>decoding &amp; error handling</strong>? </p>
  
  <p>Thanks in advance :)</p>