안녕하세요 iOS 개발자 워너비 루크입니다
오늘은 ALamofire 라이브러리를 한번 파헤쳐 보려고 합니다
깃헙 라이브러리의 영문 문서를 번역해 볼 거에요 ㅎ
번역하면서 느낀점은... 유명한 라이브러리들은 모두 사용법이 매우 친절하다는 점입니다..
애플공식문서랑 문체가 비슷한 느낌이 들정도로요...
저도 나중에 이런 라이브러리의 컨트리뷰터가 되는 날이 오겠죠...?
번역시작하겠습니다 ㅎ
직역은 지양하는 편입니다. 최대한 읽기 편하게끔 의역을 하니 만약 오류가 있다면 피드백 부탁드립니다!
Using Alamofire
Introduction
Alamofire 는 HTTP 네트워크 요청을 위한 간편한 인터페이스를 제공합니다.
HTTP 기능을 따로 구현한 것이 아니라,
애플의 URL Loading Systerm 을 활용해 만들어진 라이브러리입니다.
Alamofire 의 핵심 시스템은 URLSession 과 URLSessionTask 로 부터 상속받은 서브클래스들입니다.
Alamofire 는 이러한 API 를 감싸서 더 쉽고 간편하게 다양한 기능의 HTTP 통신 기능을 사용할 수 있도록 돕습니다.
그럼에도 Alamofire 의 중심 동작이 어디로 부터 나오는지 알고 있어야합니다.
즉, 애플의 URL Loading System 에 대해 친숙해야합니다.
Alamofire 의 많은 네트워킹 기능들이 시스템의 용량에 의해 제한되기도 합니다.
추가적으로, Alamofire 의 네트워킹(URL Loading System) 은 비동기적으로 실행됩니다.
따라서 비동기 프로그래밍 개념에 대한 이해 또한 필요합니다.
Alamofire 의 이전 버전에서는 Alamofire.request() 라는 예시를 사용했습니다.
이 API 에서는 Alamofire prefix 가 필요한 것 처럼 나타내어져 있지만, 사실 없어도 괜찮습니다.
import Alamofire 를 한 모든 파일에서 글로벌하게 request 메서드를 사용할 수 있습니다.
Alamofire 5 부터는 이 기능이 제거되었습니다.
대신 AF 키워드를 통해 글로벌하게 Session.default 를 참조하게 됩니다.
이를 통해 더이상 Session API 를 글로벌하게 복제할 필요가 없어졌으며 gloabal 네임 스페이스를 오염시키지 않으면서 같은 기능을 간편하게 제공할 수 있게 되었습니다.
유사하게 af 프로퍼티를 extension 해, Alamofire 의 기능과 다른 extension 의 기능들을 분리해둘 수 있습니다.
Making Requests
Alamofire 에서의 HTTP request 는 정말 간편합니다.
URL 을 String 으로 전달하는 것만으로 response 를 받아올 수 있습니다.
모든 예시는 import Alamofire 를 한 파일에서만 사용가능합니다.
AF.request("https://httpbin.org/get").response { response in
debugPrint(response)
}
Swift
복사
request 메서드의 정의는 아래와 같습니다.
open func request<Parameters: Encodable>(_ convertible: URLConvertible,
method: HTTPMethod = .get,
parameters: Parameters? = nil,
encoder: ParameterEncoder = URLEncodedFormParameterEncoder.default,
headers: HTTPHeaders? = nil,
interceptor: RequestInterceptor? = nil) -> DataRequest
Swift
복사
이 메서드는 DataRequest 를 생성합니다.
파라미터
•
convertible : 모든 URL 로 변환가능한 타입의 값을 전달 받습니다.
•
method : HTTP 메서드의 타입을 결정할수 있습니다
◦
예: GET, POST, PUT, DELETE,PATCH
•
parameters :
•
encoder : 어떤 형식으로 인코딩을 할것인지에 따른 인코더를 결정할 수 있습니다
◦
예 : JSON 인코더
•
headers:
•
interceptor:
이 API 의 두번쨰 버전은 더 간단합니다.
open func request(_ urlRequest: URLRequestConvertible,
interceptor: RequestInterceptor? = nil) -> DataRequest
Swift
복사
모든 URL 로 변환가능한 타입(URLRequestConvertible 프로토콜을 준수하는 타입)의 값을 전달 받습니다.
메서드는 이 타입에 대한 DataRequest 를 생성합니다.
앞선 버전의 파라미터들은 모두 위 값안에 캡슐화 되어 있습니다.
HTTP Methods
HTTPMethod 타입은 HTTP 메서드들을 정의해놓았습니다,
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
}
}
Swift
복사
AF.requset 에 다음과 같이 활용이 가능합니다
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)
Swift
복사
HTTP 메서드들은 다른 의미를 가지고 있기 때문에 서버가 기대하는 방식의 파라미터 인코딩이 필요합니다.
따라서 기억을 잘해두고 잘 써먹어야 겠죠?
예를들어, GET 요청에서는 body 데이터를 포함시킬 수 없습니다.
에러가 발생해요!
Alamofire 는 URLRequest 의 extension 또한 제공해요.
이 확장은 httpMethod 프로퍼티와 브릿징(호환) 됩니다!
public extension URLRequest {
/// Returns the `httpMethod` as Alamofire's `HTTPMethod` type.
var method: HTTPMethod? {
get { return httpMethod.flatMap(HTTPMethod.init) }
set { httpMethod = newValue?.rawValue }
}
}
Swift
복사
만약 Alamofire 가 사용하고자 하는 HTTPMethod 를 제공하지 않는다면 custom value 를 추가하면 된답니다.
extension HTTPMethod {
static let custom = HTTPMethod(rawValue: "CUSTOM")
}
AF.request("https://httpbin.org/headers", method: .custom)
Swift
복사
Setting Other URLRequest Properties
Alamofire 의 request 생성 메서드는 커스텀을 위한 흔한 파라미터를 제공하지만,
가끔은 불충분할 때가 있을 수 있죠.
파라미터들에 의해 생성된 URLRequest 는 RequestModifier 클로져를 사용함으로써 변경이 가능합니다.
예를 들어, URLRequest 의 timoutInterval 이 5초로 설정하고자 한다면 .
클로져 내부에서 request 를 수정하면 됩니다.
AF.request("https://httpbin.org/get", requestModifier: { $0.timeoutInterval = 5 }).response(...)
Swift
복사
RequestModifier 는 trailing closuer 구문으로도 사용이 가능합니다.
AF.request("https://httpbin.org/get") { urlRequest in
urlRequest.timeoutInterval = 5
urlRequest.allowsConstrainedNetworkAccess = false
}
.response(...)
Swift
복사
RequestModifier 는 URL 을 사용해서 만들어진 request 에만 적용이 가능합니다.
URLRequestConvertible 를 준수하는 값으로 부터 직접 생성된 값에는 적용이 불가능해요!
생성시에 request가 한번 수정되어야 하는 경우에 만 URLRequestConvertible 타입을 사용하는 것을 추천 드립니다
나중에 변경이 불가능하니까요! ㅎㅎ
Request Parameters and Parameter Encoders
Alamofire 는 Encodable 을 준수하는 타입을 요청에 대한 파라미터로 사용할 수 있습니다.
이렇게 전달된 파라미터들은 ParameterEncoder 프로토콜을 준수하는 타입에 전달됩니다.
그 후 URLRequest 에 추가 되어 네트워크로 보내지죠.
Alamofire에는 기본적으로 ParameterEcoder 을 준수하는 2가지 타입이 존재합니다.
•
JSONParameterEncoder
•
URLEncodedFormParameterEncoder
이 두 타입은 요새 핫한 대부분의 인코딩 서비스를 제공합니다
struct Login: Encodable {
let email: String
let password: String
}
let login = Login(email: "test@test.test", password: "testPassword")
AF.request("https://httpbin.org/post",
method: .post,
parameters: login,
encoder: JSONParameterEncoder.default).response { response in
debugPrint(response)
}
Swift
복사
URLEncodedFormParameterEncoder
URLEncodedFormParameterEncoder 는 URL 인코딩 된 string 에 값을 인코딩해 넣습니다.
URL 쿼리 문자열에 파라미터들을 끼워넣거나, HTTP body 에 넣습니다.
인코딩된 string 을 어누부분에 끼워넣을 것인지는 destination 을 설정하면 됩니다.
URLEncodedFormParameterEncoder.Destination 열거형은 3가지 case 를 가집니다.
•
.methodDependent : get, head, delete 요청을 나태내느 쿼리에 기반하여 어디에 넣을 지 판단합니다. 인코딩된 쿼리 string 을 HTTP body 또는 HTTP 메서드의 request 에 적용합니다.
•
.queryString : 인코딩된 string 은 URL request 의 쿼리에 추가합니다
•
.httpBody : 인코딩된 string 을 URLRequest 의 HTTP body 추가합니다.
The Content-Type HTTP header of an encoded request with HTTP body is set to application/x-www-form-urlencoded; charset=utf-8, if Content-Type is not already set.
Internally, URLEncodedFormParameterEncoder uses URLEncodedFormEncoder to perform the actual encoding from an Encodable type to a URL encoded form String. This encoder can be used to customize the encoding for various types, including Array using the ArrayEncoding, Bool using the BoolEncoding, Data using the DataEncoding, Date using the DateEncoding, coding keys using the KeyEncoding, and spaces using the SpaceEncoding.
아직 이부분은 정확하게 이해를 못하게 두어서 원문으로 두겠습니다! 강해져서 돌아올게요!
let parameters = ["foo": "bar"]
// All three of these calls are equivalent
AF.request("https://httpbin.org/get", parameters: parameters) // encoding defaults to `URLEncoding.default`
AF.request("https://httpbin.org/get", parameters: parameters, encoder: URLEncodedFormParameterEncoder.default)
AF.request("https://httpbin.org/get", parameters: parameters, encoder: URLEncodedFormParameterEncoder(destination: .methodDependent))
// https://httpbin.org/get?foo=bar
Swift
복사
위 세줄의 코드는 모두 같은 요청을 합니다!
let parameters: [String: [String]] = [
"foo": ["bar"],
"baz": ["a", "b"],
"qux": ["x", "y", "z"]
]
// All three of these calls are equivalent
AF.request("https://httpbin.org/post", method: .post, parameters: parameters)
AF.request("https://httpbin.org/post", method: .post, parameters: parameters, encoder: URLEncodedFormParameterEncoder.default)
AF.request("https://httpbin.org/post", method: .post, parameters: parameters, encoder: URLEncodedFormParameterEncoder(destination: .httpBody))
// HTTP body: "qux[]=x&qux[]=y&qux[]=z&baz[]=a&baz[]=b&foo[]=bar"
Swift
복사
위 세줄의 post request 도 차만가지로 같은 요청을 보냅니다.
다만 이번엔 메서드가 post 이므로 post 방식에 맞게 HTTP body 에 파라미터가 인코딩되어 삽입된 모습이죠!
진짜 간편해보이네요,,, 왜 쓰는지 알겠다
Configuring the Sorting of Encoded Values
Swift 4.2 부터 Dictionary 는 앱 실행시마다 내부적으로 순서가 뒤바뀝니다(랜덤)
이 현상은 인코딩된 파라미터들의 순서가 뒤바뀔 수 있다는 점에서 중요합니다...
기본적으로 URLEncodedFormEncoder 는 인코딩된 키 밸류 쌍을 sorting 합니다.
이러한 과정은 Encodable 을 준수하는 타입의 결과물로 항상 일정하지만, 타입에 구현된 실제 인코딩 순서와는 맞지 않을 수 있습니다.
alphabetizeKeyValuePairs 를 false 로 설정해서 구현한 순서대로 인코딩 되도록 할 수 있/습니다.
Dictionary 의 순서가 랜덤하더라도 말이지요.
URLEncodedFormParameterEncoder 를 새로 만들어서 alphabetizeKeyValuePairs 를 명시해줄 수 잇습니다.
let encoder = URLEncodedFormParameterEncoder(encoder: URLEncodedFormEncoder(alphabetizeKeyValuePairs: false))
Java
복사
Configuring the Encoding of Array Parameters
JSONParameterEncoder
JSONParameterEncoder 는 Encodable 한 값들은 Swift 의 JSONEncoder 를 사용하여 인코딩합니다.
그렇게 인코딩된 결과는 URLRequest 의 httpBody 에 삽입됩니다.
인코딩된 request 의 HTTP header 필드중 Content-Type는 application/json 으로 설정해주어야합니다!!
AF.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: ["Content-Type" : "application/json", "Accept":"application/json"])
Java
복사
Configuring a Custom JSONEncoder
JSONParameterEncoder 의 동작을 커스터마이징할 수 있습니다.
원하는 대로 JSONEncoder의 인스턴스를 생성해서 JSONParameterEncoder 의 파라미터로 전달해주면 됩니다.
let encoder = JSONEncoder()
encoder.dateEncoding = .iso8601 // 커스텀 1
encoder.keyEncodingStrategy = .convertToSnakeCase // 커스텀 2
let parameterEncoder = JSONParameterEncoder(encoder: encoder) // 인스턴스를 활용해 인스턴스 생성
AF.request(url, method: .get, parameters: nil, encoder: encoder, headers: ["Content-Type" : "application/json", "Accept":"application/json"])
Java
복사
let url = URL(string: "https://httpbin.org/get")!
var urlRequest = URLRequest(url: url)
let parameters = ["foo": "bar"]
let encodedURLRequest = try URLEncodedFormParameterEncoder.default.encode(parameters,
into: urlRequest)
Java
복사
ParameterEncoder API 는 Alamofire 밖에서도 사용이 가능합니다.
URLRequest 의 파라미터를 인코딩하는데 직접적으로 사용이 가능해요!
HTTP Headers
Alamofire 에는 HTTPHeaders 타입이 존재합니다.
이 타입은 HTTP 헤더의 name value 쌍을 순서 보존적이고, case-insensitive(?) 하게 나타냅니다.
HTTPHeader 타입들은 한쌍의 name value 페어를캡슐화할 뿐더러, 자주 사용되는 헤더들에 대해 static value 를 제공합니다!
커스텀 HTTPHeaders 를 Request 에 값으로 건네주면 됩니다. (편하죠?
let headers: HTTPHeaders = [
"Authorization": "Basic VXNlcm5hbWU6UGFzc3dvcmQ=",
"Accept": "application/json"
]
AF.request("https://httpbin.org/headers", headers: headers).responseDecodable(of: DecodableType.self) { response in
debugPrint(response)
}
Swift
복사
HTTPHeaders 는 HTTPHeader 값들의 배열로 구성할 수 도 있습니다!
let headers: HTTPHeaders = [
.authorization(username: "Username", password: "Password"),
.accept("application/json")
]
AF.request("https://httpbin.org/headers", headers: headers).responseDecodable(of: DecodableType.self) { response in
debugPrint(response)
}
Swift
복사
가독성이 좋아졌죠?
앱 내에서 바꾸지 않고 사용되는 HTTP 헤더들은 URLSessionConfiguration 에 설정해둠으로써 URLSession 에서 생성되는 모든 URLSessionTask 에 자동으로 적용할 수 있습니다!!
Alamofire 의 Session 은 모든 Request 에 대해 기본 헤더값을 가집니다.
그 값들은 아래와 같습니다.
•
•
Accept-Language, which defaults to up to the top 6 preferred languages on the system, formatted like en;q=1.0, per RFC 7231 §5.3.5.
•
User-Agent, which contains versioning information about the current app. For example: iOS Example/1.0 (com.alamofire.iOS-Example; build:1; iOS 13.0.0) Alamofire/5.0.0, per RFC 7231 §5.5.3.
이러한 헤더값을 커스터마이징할 필요가 있다면 URLSessionConfiguration 을 생성해야합니다.
headers 프로퍼티는 업데이트 되어야하며, configuration 을 새 Session 인스턴스에 적용되어야합니다.
URLSessionConfiguration.af.default 을 사용해서 Alomfire 의 기본 헤더들을 유지하면서 새 구성을 커스터마이징하세요
Response Validation
기본적으로 Alamofire 는 response 의 컨텐츠와는 상관없이
reponse 핸들러 이전에 validate() 를 호출해서 에러를 발생시킬 수 있습니다.
허용불가능한 status code 또는 MIME type 을 걸러내는 데 이 메서드를 호출하세요
Automatic Validation
validate() API 는 자동으로
•
status code 가 200..<300 안에 해당하는지 확인하고,
•
response의 Content-Type 헤더의 값이 request 의 Accept 헤더 값과 일치하는지 확인합니다
AF.request("https://httpbin.org/get").validate().responseData { response in
debugPrint(response)
}
//위 코드는 아래와 동일한 response 를 받아옵니다.
AF.request("https://httpbin.org/get")
.validate(statusCode: 200..<300)
.validate(contentType: ["application/json"])
.responseData { response in
switch response.result {
case .success:
print("Validation Successful")
case let .failure(error):
print(error)
}
}
Swift
복사
Response Handling
제일 중요하다고도 할 수 잇는 파트인 것 같네요.
Alamofire 에는 두가지 request 방식이 존재합니다.
•
DataRequest
•
DownloadRequest
가 바로 그것인데요.
두 방식 모두 각자에 해당하는 response type을 가집니다
•
DataResponse<Success, Failure: Error>
•
DownloadResponse<Success, Failure: Error>
이 두가지 response 타입 둘다 동일한 두개의 제네릭으로 구성되어있습니다!
기본적으로 모든 response 값은 AFError 타입을 생성합니다.
Alamofire 는 더간단한
•
AFDataResponse<Success>
•
AFDownloadResponse<Success>
를 사용합니다
이 public API 내부에는 AFError 의 에러타입을 항상 보유합니다.
DataRequest 의 서브클래스인 UploadRequest 도 똑같이 DataResponse 타입을 사용합니다.
Alamofire 에서 만들어진 DataRequest 와 UploadRequest 의 DataResponse 를 다루는 데에는,responseDecodable 와 같은 response handler 를 체이닝하면 됩니다.
AF.request("https://httpbin.org/get").responseDecodable(of: DecodableType.self) { response in
debugPrint(response)
}
Swift
복사
위 예시에서 responseDecodable 핸들러는 DataRequest 에 더해져 사용되고 잇습니다.
DataRequest 의 실행이 완료되면 핸들러가 실행됩니다.
핸들러로 전달된 클로져는 DataResponse<DecodableType, AFError> 의 값을 받아서
서버로 부터 응답이 올때까지 실행이 block 되는 것이 아닙니다!
이 클로져는 callback 에 추가되어 응답왔을 때, 실행됩니다.
request 의 결과는 response 클로져 내무에서만 사용이 가능합니다.
즉, 모든 response 데이터에 대한 가공은 이 클로져 내부에서 실행되어야합니다.
Alamofire 에는 5가지 다른 data response 핸들러들이 있습니다.
// Response Handler - Unserialized Response
func response(queue: DispatchQueue = .main,
completionHandler: @escaping (AFDataResponse<Data?>) -> Void) -> Self
// Response Serializer Handler - Serialize using the passed Serializer
func response<Serializer: DataResponseSerializerProtocol>(queue: DispatchQueue = .main,
responseSerializer: Serializer,
completionHandler: @escaping (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 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
Swift
복사
Response Handler
response 핸들러는 어떠한 response 데이터도 평가하지 않습니다.
단순히 모든 정보를 URLSessionDelegate 로부터 직접 받아오기만 합니다.
AF.request("https://httpbin.org/get").response { response in
debugPrint("Response: \(response)")
}
Swift
복사
Response 의 Result 타입의 장점을 활용하려면 다른 response seriailizer 를 사용하는 것이 좋습니다
Response Data Handler
responseData 핸들러는 DataResponseSeriailizer 를 사용해서 Data 를 추출하고 유효화 합니다.
만약 에러가 발생하지 않고 Data 가 반환되면, response 의 Result 값에는 .success 가 담겨있을 것입니다.
value 는 Data 타입으로 반환됩니다.
AF.request("https://httpbin.org/get").responseData { response in
debugPrint("Response: \(response)")
}
Swift
복사
Response String Handler
responseString 핸들러는 StringResponseSerializer 를 사용해서 Data 를 추출하고 String 타입으로 변환 합니다.
만약 에러가 발생하지 않고 Data 가 String 으로 변환되면, response 의 Result 값에는 .success 가 담겨있을 것입니다.
value 는 String 타입으로 반환됩니다.
AF.request("https://httpbin.org/get").responseData { response in
debugPrint("Response: \(response)")
}
Swift
복사
Response Decodable Handler
responseDecodable 핸들러는 DecodableResponseSerializer 를 사용해서 Data 를 추출하고 , 전달해준 Decodable 타입으로 변환합니다.
이 과정은 명시된 DataDecoder 에 의해 이루어집니다.
에러가 발생하지 않고 모든 서버 데이터가 Decodable 타입으로 디코딩 되면 response 의 Result 는 .success 값이 들어 있습니다.
또한 value 에는 전달된 타입으로 변환된 인스턴스가 존재합니다.
만약 에러가 발생하지 않고 Data 가 반환되면, response 의 Result 값에는 .success 가 담겨있을 것입니다.
struct DecodableType: Decodable { let url: String }
AF.request("https://httpbin.org/get").responseDecodable(of: DecodableType.self) { response in
debugPrint("Response: \(response)")
}
Swift
복사
Chained Response Handlers
response 핸들러는 연달아 사용도 가능합니다.
Alamofire.request("https://httpbin.org/get")
.responseString { response in
print("Response String: \(response.value)")
}
.responseDecodable(of: DecodableType.self) { response in
print("Response DecodableType: \(response.value)")
}
Swift
복사
단 이경우 네트워크로 부터 데이터를 두번 요청합니다. 따라서 디버깅용도로만 사용하세요
Response Handler Queue
response 핸들러에 전달된 클로져는 .main 큐 에서 실행됩니다.
하지만 구체적인 DispatchQueue 를 명시해주어 이 큐에서 실행하도록 할 수 있습니다.
실질적인 serialization 작업(데이터 >> 다른 타입으로의 변환 )은 항상 백그라운드(rootQueue 또는 serializationQueue)에서 실행됩니다.
let utilityQueue = DispatchQueue.global(qos: .utility)
AF.request("https://httpbin.org/get").responseDecodable(of: DecodableType.self, queue: utilityQueue) { response in
print("This closure is executed on utilityQueue.")
debugPrint(response)
}
Swift
복사
Response Caching
Authentication
인증은 system framework 수준의 URLCredential 과 URLAuthenticationChallenge 에 의해서 이루어집니다.
HTTP Basic Authentication
Request 의 authenticate 메서드를 사용하면 자동으로 URLCredential 을 제공합니다.
let user = "user"
let password = "password"
AF.request("https://httpbin.org/basic-auth/\(user)/\(password)")
.authenticate(username: user, password: password)
.responseDecodable(of: DecodableType.self) { response in
debugPrint(response)
}
Swift
복사
Authentication with URLCredential
URLCredential 을 직접 선언하여 전달할 수 도 있습니다.
let user = "user"
let password = "password"
let credential = URLCredential(user: user, password: password, persistence: .forSession)
AF.request("https://httpbin.org/basic-auth/\(user)/\(password)")
.authenticate(with: credential)
.responseDecodable(of: DecodableType.self) { response in
debugPrint(response)
}
Swift
복사
Manual Authentication
항상 Authenticate 가 필요한 API 와 통신한다거나 유사한 헤더가 필요하다면, 수동으로 추가해줄 수 있습니다
let user = "user"
let password = "password"
let headers: HTTPHeaders = [.authorization(username: user, password: password)]
AF.request("https://httpbin.org/basic-auth/user/password", headers: headers)
.responseDecodable(of: DecodableType.self) { response in
debugPrint(response)
}
Swift
복사
작성예정