루픽코드
/** 첫번째파라미터에는 method파라미터에는 post 방식, 세번째는 요청할 쿼리파라미터를 param 으로 넣음
딕셔너리로 파라미터 형태로 전달을 하면 알아서 유알엘 뒤에 쿼리파라미터를 추가해준다.*/
AF.request(path, method: .post, parameters: params,
encoding: JSONEncoding(options: []), headers: headers).responseJSON {
(response:AFDataResponse<Any>) in
public func login(_ path:String, params:[String : Any], completion: @escaping (_ result: JSON) -> Void) {
if !Reachability.isConnectedToNetwork() {
completion(JSON(["return":false, "code":"NET_MSG_0000"]))
return
}
let headers:HTTPHeaders = ["Content-Type": "application/json",
"Accept-Charset": "charset=UTF-8"]
console.d(path, params)
/** 첫번째파라미터에는 method파라미터에는 post 방식, 세번째는 요청할 쿼리파라미터를 param 으로 넣음
딕셔너리로 파라미터 형태로 전달을 하면 알아서 유알엘 뒤에 쿼리파라미터를 추가해준다.*/
/** 리퀘스트 메서드를 이용해 API를 호출하였으면 응답데이터를 받을 수 있는 메서드를 체이닝해줘야한다,
.responseData(completionHandler: */
AF.request(path, method: .post, parameters: params,
encoding: JSONEncoding(options: []), headers: headers).responseJSON
{ (response:AFDataResponse<Any>) in
#if DEBUG
// debugPrint(response)
#endif
/** 요청에 대한 응답결과는 이렇게 적는다. 열거형으로 되어있어서 switch문으로 작성*/
switch response.result {
case .success(let data):
if String(describing: data).contains("error") {
#if DEBUG
print("An error has occurred.")
#endif
var message = JSON(data)["message"].stringValue
if "" == message {
message = "service_error".localized()
}
completion(JSON(["return":false, "code":"API_MSG_0000", "message":message]))
break
}
completion( JSON(data) )
break
case .failure(let error):
#if DEBUG
print(error)
#endif
completion(JSON(["return":false, "code":"API_MSG_0000", "message":"service_error".localized()]))
}
}
}
패캠 코드
func fetchCovidOverView(
completionHandler: @escaping Result<CityCovidOverView, Error>) -> Void
) {
let url = "<http://www.bbbb.com>"
let param = ["API키": "g33ighowgogiig"]
AF.request(url, method: .get, parameter: param)
.resoponseData(completionHandler: { response in
switch response.result {
case let .success(data):
do{
let decoder = JSONDecoder()
let result = try decoder.decode(CityCovidOverView.self, from: data)
completionHandler(.success(result))
} catch {
completionHandler(.failure(error))
}
}
case let .failure(error):
complertionHandler(.failure(error))
}
})
}
}
<aside> 💡 @escaping 이라는 탈출 클로저를 사용하는 이유!
예시
서버에서 이미지를 받아와서 UIImage형 변수에 저장하는 함수가 있다고 가정!
func setImage(url: String) -> UIImage {
var result = UIImage()
Alamofire.request(url).responseImage { (response) in
if let image = response.result.value {
result = image
}
}
}
<aside> 💡 Alamofire 를 활용한 request는 동기적으로
var result = UIImage()가 끝나고 → Alamofire.request 가 끝나고 → return result 가 되는것이 아니라!
Alamofire.request는 비동기적으로 실행시켜놓고 Alamofire의 완료 여부와 상관없이 따로 return result가 실행된다.
즉, retrun result 가 실행되기 이전에 서버에서 이미지를 받아오는 부분이 안끝나면 빈 이미지가 return 되기때문에 서버에서 이미지를 받아오는 부분이 끝나고 정상적인 이미지가 넘어와야한다!
그래서 @escaping 클로저를 활용하게 된다.
</aside>
❌ 탈출클로저를 사용하지 않았을 경우
→ 함수가 리턴되기전에 서버 작업 완료되었는지 보장이 되지않는다.