앱을 개발하다 보면, 서버와 통신하는 부분이 필수적이다. 이럴 때, 기본으로 제공하는 Foundation의 URLSession을 사용할 수 있다.
하지만, URLSession은 다소 번거로운 점이 있기 때문에 Alamofire를 주로 사용한다.
전에 다른 포스팅을 하면서 잠깐 언급했던 적이 있다.
Alamofire는 다음 기능들을 제공하는데, 이 외에도 다양한 기능을 제공한다.
즉, Alamofire는 HTTP 네트워킹을 하는데 있어서 자주 사용하는 코드 및 함수를 쉽게 사용할 수 있도록 한다.
여기서! 알아야 하는 게 하나 더 있다.
바로 Request Methods
이다.
Request Methods는 클라이언트(우리는 앱임!)가 서버에게 사용자 요청의 목적이나 종류를 알리는 수단이다.
요청 종류로는 여러가지가 있다.
서버의 여러 정보를 확인하기 위해 사용되는 메소드이다. Reponse Body가 없고, Response Code와 HEAD만 응답받는다.
HEAD /index.html
서버의 데이터를 가져올 때 사용하는 메서드이다. 굉장히 자주 쓰인다. Request Body가 없어, 전달할 내용을 header에 담는다.
즉, URI에 전달할 내용이 담기기 때문에 누구나 해당 내용을 볼 수 있다.
GET /index.html
서버로 데이터를 전송할 때 사용하는 메서드로, 요청 유형은 Content-Type 헤더로 나타낸다. 전달할 내용을 Request Body에 담는다.
POST / HTTP/1.1
Host: foo.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 13
say=Hi&to=Mom
새로운 리소스를 생성하거나, 기존 리소스를 변경할 때 사용하는 메서드이다.
PUT /new.html HTTP/1.1
Host: example.com
Content-type: text/html
Content-length: 16
<p>New File</p>
서버에 있는 특정 리소스를 삭제하기 위해 사용하는 메서드이다.
DELETE /file.html HTTP/1.1
이밖에도 PATCH
, OPTIONS
등 여러 가지가 더 있지만..
개인적으로 잘 안 쓰는(?) 것 같아서 정리 안 했다.
아님 말구요..ㅠ
이제 요청 종류도 알았으니 직접 사용해보자!
let url = "https://어쩌구저쩌구"
AF.request(url,
method: .get,
parameters: nil,
encoding: URLEncoding.default,
headers: ["Content-Type":"application/json", "Accept":"application/json"])
.validate(statusCode: 200..<300)
.responseJSON { response in
/** 서버로부터 받은 데이터 활용 */
switch response.result {
case .success(let data):
/** 정상적으로 reponse를 받은 경우 */
case .failure(let error):
/** 그렇지 않은 경우 */
}
}
url
: 먼저 첫 번째 파라미터로 요청할 url을 담는다.
method
: 어떤 request method를 사용할 것인지를 나타낸다.
parameters
: POST 메서드와 같이 request body를 사용할 때 전달할 값을 담는다.
encoding
: 인코딩 방식을 정한다.
headers
: 부가적인 정보를 나타낸다. 위에서는 송/수신 데이터 타입(JSON)을 나타낸다.
validate
: 유효성을 검사한다. state code 값이 20x일 때가 송/수신이 원활하게 된 경우.
responseJSON
: 응답 json 데이터이다.
앞에서 GET 메서드의 사용 예시를 살펴봤으니, 이번에는 POST 메서드를 사용해보자.
위에서 잠깐 설명했는데, POST 메서드를 사용할 때는 parameters
를 이용하면 된다.
let url = "https://어쩌구저쩌구"
let params = ["id":"아이디", "pw":"패스워드"] as Dictionary
AF.request(url,
method: .post,
parameters: params,
encoding: JSONEncoding(options: []),
headers: ["Content-Type":"application/json", "Accept":"application/json"])
.responseJSON { response in
/** 서버로부터 받은 데이터 활용 */
switch response.result {
case .success(let data):
/** 정상적으로 reponse를 받은 경우 */
case .failure(let error):
/** 그렇지 않은 경우 */
}
}
위처럼 parameters
에 값을 담으면, request body에 해당 값을 담아 서버로 보낸다.
Alamofire를 사용해서 파일을 다운로드 하거나, 업로드 하는 것도 가능하다.
let url = "https://어쩌구저쩌구"
AF.upload(multipartFormData: { multipartData in
/** 서버로 전송할 데이터 */
}, to: url,
method: .post,
headers: ["Content-Type" : "multipart/form-data"])
.response { response in
if response.error != nil {
/** 파일 업로드 실패*/
} else{
/** 파일 업로드 성공*/
}
}
이때, GET이나 POST 메서드를 사용할 때는 header의 Content-Type가 application/json
이었다.
하지만 파일을 업로드 하거나 다운로드할 때는 Content-Type을 multipart/form-data
로 작성해야 한다.
데이터는 다음과 같이 전달할 수 있다.
먼저, request body를 추가할 때는 for문을 사용해 key value 값을 추가한다.
for (key, value) in parameters {
multipartFormData.append("\(value)".data(using: .utf8)!, withName: key)
}
이미지를 추가할 때는 다음과 같이 나타낸다.
if let image = imageData?.pngData() {
multipartFormData.append(image, withName: "activityImage", fileName: "\(image).png", mimeType: "image/png")
}
value
: 전달할 파일
withName
: key
fileName
: 서버에 업로드할 파일 이름
mimeType
: 파일 형식
let url = "https://어쩌구저쩌구/test.jpg"
/** 파일에 저장하기 위한 코드 */
let fileManager = FileManager.default
let appURL = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
let fileName : String = URL(string: url)!.lastPathComponent /** url의 마지막 문자열로 이름 지정 */
let fileURL = appURL.appendingPathComponent(fileName)
/** 파일 경로 지정 및 다운로드 옵션 설정 (이전 파일 삭제, 디렉토리 생성) */
let destination: DownloadRequest.Destination = { _, _ in
return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
}
AF.download(url,
method: .get,
parameters: nil,
encoding: JSONEncoding.default,
to: destination)
.downloadProgress { progress in
/** 다운로드 progress */
/** progressView를 사용할 때 여기에 작성 */
}.response{ response in
if response.error != nil {
/** 파일 다운로드 실패*/
} else{
/** 파일 다운로드 성공*/
}
}
이정도만 알아도,
당신은 네트워크 통신 『master』 ...
아마두
좋은정보 감사합니다 !!