본문 바로가기

MOBILE/ios

[iOS] Alamofire를 사용하여 비동기 서버 통신하기

0. Alamofire

iOS 에서는 URLSession이라는 데이터/서버 통신용 프레임워크를 제공하지만 이는 사용하기 매~우 불편하다.

Alamofire는 이러한 URLRequest + URLSession를 래핑한 구조를 가진 라이브러리이다.

즉 네트워킹 도구이다.

 

이 라이브러리를 사용하고자 한다면 기본적인 네트워킹 지식이 필요하다.

 

[iOS] URLSession을 사용하여 POST method 통신하기

HTTP의 기본 구조 HTTP는 요청을 일정한 형식의 텍스트 기반 메세지로 변환한 메세지 형식을 말한다. 크게 요청, 응답으로 구분된다. 메세지는 모두 다음과 같은 구조이다. Line - Header - Body Line은 메

josushell.tistory.com

 

1. Alamofire 프로젝트에 반입하기

Alamofire는 SPM, cocoapods 두 가지 방법 모두 사용하여 반입할 수 있다.

 

GitHub - Alamofire/Alamofire: Elegant HTTP Networking in Swift

Elegant HTTP Networking in Swift. Contribute to Alamofire/Alamofire development by creating an account on GitHub.

github.com

하지만 난 SPM 귀찮으니까 그냥 cocoapod을 써서 설치를 한다...

pod 'Alamofire'

 

2. Alamofire 기본 메소드: 요청

Alamofire에서 제공하는 네트워킹을 요청 메소드는 다음과 같다.

Method Description
upload() 스트림, 파일 메소드 등을 통해 파일을 업로드한다.
download() 파일을 다운로드 한다.
request()  기본적인 HTTP 요청

 

 

사용 예시는 다음과 같다.

Alamofire는 전송 방식을 지정하지 않으면 GET 방식으로 보낸다. 따라서 다른 방식의 네트워킹을 원한다면 HTTPMethod 열거형 객체에 있는 값을 method에 넣어주고 호출하면 된다.

 

5.1에서 변경되어서 모듈에 접근할 때는 Alamofire 대신에 AF를 사용한다.

// GET
AF.request("url")

// POST
AF.request("url", method: .post)

 

파라미터가 있는 POST 방식을 호출하기 위해서는 param 파라미터에 딕셔너리 형태로 값을 넣어준다.

(참고로 GET 방식에서 body에 값을 넣는것은 지원하지 않는다.)

 

// 기본 POST 방식
let param: Parametres = ["id": "myid", "name" : "sueyeon"]
AF.request("url", method: .POST, parameters: param)

// 값에 한글 등의 특수 문자가 포함되는 경우
let param: Parametres = ["id": "sueyeon!!", "name" : "특수 문자 넣어줭"]
AF.request("url", method: .POST, parameters: param, encoding: URLEncoding.httpBody)

// JSON 타입으로 값을 보내는 경우
let param: Parametres = ["id": "sueyeon!!", "name" : "json으로 보내줭"]
AF.request("url", method: .POST, parameters: param, encoding: JSONEncoding.default)

 

특수문자가 포함되면 encoding 파라미터를 통해서 인코딩을 해줘야 값이 제대로 나온다.

encoding 파리미터에는 ParameterEncoding 프로토콜을 구현한 열거형, 클래스, 구조체 객체를 넣을 수 있다.

 

주로 URLEncoding 객체를 사용가능하며 이걸로 거의 대부분 커버 가능하다.

타입이 3가지의 static 변수로 선언되어 있다.

Type Description
.methodDependent 메소드에 따라 인코딩 타입이 자동으로 결정된다.
.queryString GET 방식에서 사용되는 쿼리 스트링 방식으로 인코딩한다.
.httpMethod POST 방식에서 사용되는 HTTP Body 방식으로 인코딩한다.

 

만약에 JSON 방식으로 값을 전송한다면 URLEncoding 객체가 아닌 JSONEncoding 객체를 사용해야 한다.

이처럼 Alamofire에서는 encoding 타입을 설정하면 알아서 Content-Type 헤더에 자동으로 설정되기 때문에 직접 설정하지 않아도 된다. 하지만 특별히 헤더에 값을 추가하고 싶다면 다음을 사용한다.

// header를 따로 추가하고 싶은 경우
let header: HTTPHeaders = ["header": "헤?더?"]
AF.request("url", method: .POST, parameters: param, encoding: JSONEncoding.default, headers: header)

주로 Authorization을 설정할 때 사용하게 된다.

 

 

메소드 방식은 다음을 참고하면 된다.

https://tools.ietf.org/html/rfc7231#section-4.3

 

RFC 7231: Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content

 

www.rfc-editor.org

파일을 까보면 다음과 같이 HTTPMethod 열거형을 볼 수 있다.

 

 

 

3. Alamofire 기본 메소드:  응답

기본 응답 처리 메소드는 다음과 같다.

Method Description
response() 응답 메세지를 따로 처리하지 않는다. 즉 아무 기능을 제공하지 않음(굳이 안씀)
responseString() 응답 메세지의 본문을 문자열로 처리한 후 전달한다.
responseDecodable() 응답 메세지의 본문을 JSON 객체로 변환하여 전달한다.
responseData() 응답 메세지의 본문을 바이너리 데이터로 변환하여 전달한다.

 

Alamofire는 비동기 네트워킹을 지원하기 때문에 바로 메세지를 받는 것이 아니라 클로저를 통해서 동작을 정의해야 한다.

서버에서 온 응답을 DataResponse 타입의 객체로 처리하고 클로저의 매개변수에 이를 담아 호출한다.

동작 예시는 다음과 같다.

// 응답 메세지
AF.request(url).responseString() { response in
    print("성공: \(response.result.isSuccess)")
    print("결과: \(response.result.value!)")
}

 

DataResponse 객체는 다음을 참고하면 된다.

 

 

만약 JSON 객체 타입으로 response를 받는다면 decoder를 받을 클래스 모델을 정의해서 다음과 같이 사용해야 한다.

.responseDecodable(of: DecoderClass.self) { response in
    response.result // result 타입
    response.value // 디코딩된 모델 
 
}