(swift) BASIC_11. Alamofire

Reading time ~2 minutes

[swift] BASIC_11. Alamofire


Alamofire

Alamofire란

Swift 기반의 HTTP 네트워킹 라이브러리이다. URLSession에 기반한 라이브러리로, 네트워킹 작업을 단순화하고, 네트워킹을 위한 다양한 메서드와 JSON 파싱을 제공한다.



Alamofire 특성

  • 연결가능한 Request, Response 메서드를 제공한다.
  • URL JSON형태의 파라미터 인코딩을 지원한다.
  • 파일 데이터 스트링 멀티파트폼 데이터 등 업로드 기능을 제공한다.
  • HTTP Response 검증을 제공한다.
  • 광범위한 단위 테스트 및 통합 테스트를 보장한다.



URLSession 대신 Alamofire를 사용하는 이유

  • 코드의 간소화, 가독성 측면에서 도움을 준다.
  • 여러 기능을 직접 구축하지 않아도 쉽게 사용할 수 있다.


다음은 URLSession 코드이다.

// 호출 URL 만들기
var components = URLComponents(string: "https://api~~~~~~~~")!
components.queryItems = ["title": "Junhyeok"].map { (key, value) in
  URLQueryItem(name: key, value: value)
}

// Request 생성 및 실행
let request = try! URLRequest(url: components.url!, method: .get)
URLSession.shared.dataTask(with: request) { (data, response, error) in 
  do {
    guard let data = data,
      let response = response as? HTTPURLResponse, (200 ..< 300) ~= response.statusCode, error == nil
      else {
        throw error ?? Error.requestFailed
    }
    let response = try JSONDecoder().decode(Response.self, from: data)
    print("Success \(response)")
  } catch {
    print("Failure: \(error.localizedDescription)")
  }
}


이를 Alamofire를 이용하면 다음과 같이 간소화하여 가독성을 높일 수 있다.

AF.request("https://api~~~~~~~~~~", method: .get, parameters: ["title": "Junhyeok"])
  .validate()
  .responseJSON { response in
    switch response.result {
    case .success(let result):
      debugPrint("success \(result)")
    case .failure(let error):
      debugPrint("Failure \(error)")
    }
  }




Alamofire Request

// 파라미터로 URL과 HTTP 메서드 등을 쉽게 설정할 수 있다.
open func request<Parameters: Encodable>(_ convertible: URLConvertible,
                                         method: HTTPMethod = .get,
                                         parameters: Parameters? = nil,
                                         encoder: ParameterEncoder = URLEncodedFormParameterEncoder.default,
                                         headers: HTTPHeaders? = nil,
                                         interceptor: RequestInterceptor? = nil) -> DataRequest




Alamofire HTTP Method

public struct HTTPMethod: RawRepresentable, Equatable, Hashable {
  public static let connect = HTTPMethod(rawValue: "CONNECT")
  public static let delete = HTTPMethod(rawValue: "DELETE")
  public static let get = HTTPMethod(rawValue: "GET")
  public static let head = HTTPMethod(rawValue: "HEAD")
  public static let options = HTTPMethod(rawValue: "OPTIONS")
  public static let patch = HTTPMethod(rawValue: "PATCH")
  public static let post = HTTPMethod(rawValue: "POST")
  public static let put = HTTPMethod(rawValue: "PUT")
  public static let trace = HTTPMethod(rawValue: "TRACE")

  public let rawValue: String

  public init(rawValue: String) {
    self.rawValue = rawValue
  }
}


AF.request("https://httpbin.org/get")
AF.request("https://httpbin.org/post", method: .post)
AF.request("https://httpbin.org/put", method: .put)
AF.request("https://httpbin.org/delete", method: .delete)




Alamofire Response

// Response Handler - Unserialized Response
func response(queue: DispatchQueue = .main,
              completionHandler: @escaping (AFDataResponse<Data?>) -> Void) -> Self

// Response Serializer Hander - Serialize using the passed Serializer
func response<Serializer: DataResponseSerializerProtocol>(queue: DispatchQueue = .main,
                                                          responseSerializer: Serializer,
                                                          completionHandler: @escapting (AFDataResponse<Serializer.SerializedObject>) -> Void) -> Self

//Response Data Handler - Serialized into Data
func responseData(queue: DispatchQueue = .main,
                  dataPreprocessor: DataPreprocessor = DataResponseSerializer.defaultDataPreprocessor,
                  emptyResponseCodes: Set<Int> = DataResponseSerializer.defaultEmptyResponseCodes,
                  emptyRequestMethods: Set<HTTPMethod> = DataResponseSerializer.defaultEmptyRequestMethods,
                  completionHandler: @escaping (AFDataResponse<Data>) -> Void) -> Self

// Response String Handler - Serialized into String
func responseString(queue: DispatchQueue = .main,
                    dataPreprocessor: Datapreprocessor = StringResponseSerializer.defaultDataPreprocessor,
                    encoding: String.Encoding? = nil,
                    emptyResponseCodes: Set<Int> = StringResponseSerializer.defaultEmptyResponseCodes,
                    emptyRequestMethods: Set<HTTPMethod> = StringResponseSerializer.defaultEmptyRequestMethods,
                    completionHandler: @escaping (AFDataResponse<String>) -> Void) -> Self

// Response JSON Handler - Serialized into Any Using JSONSerialization
func responseJSON(queue: DispatchQueue = .main,
                  dataPreprocessor: DataPreprocessor = JSONResponseSerializer.defaultDataPreprocessor,
                  emptyResponseCodes: Set<Int> = JSONResponseSerializer.defaultEmptyResponseCodes,
                  emptyRequestMEthods: Set<HTTPMethod> = JSONResponseSerializer.defaultEmptyRequestMethods,
                  options: JSONSerialization.ReadingOptions = .allowFragments,
                  completionHandler: @escaping (AFDataResponse<Any>) -> Void) -> Self

// Response Decodable Handler - Serialized into Decodable Type
func responseDecodable<T: Decodable>(of type: T.Type = T.self,
                                     queue: DispatchQueue = .main,
                                     dataPreprocessor: DataPreprocessor = DecodableResponseSerializer<T>.defaultDataPreprocessor,
                                     decoder: DataDecoder = JSONDecoder(),
                                     emptyResponseCodes: Set<Int> = DecodableResponseSerializer<T>.defaultEmptyResponseCodes,
                                     emptyRequestMethods: Set<HTTPMethod> = DecodableResponseSerializer<T>.defaultEmptyRequestMethods,
                                     completionHandler: @escaping (AFDataResponse<T>) -> Void) -> Self



다음과 같이 사용한다.

AF.request("https://httpbin.org/get").responseJSON { response in
  debugPrint(response)
}

Gitpporter Privacy

Published on January 02, 2023

(PillSoGood) 지원

Published on November 20, 2022