Reference
- 내용전반: Apple문서
Remind
- Content-Length 헤더는 session이 알아서 알아내므로 설정할 필요가 없다
- Task는 기본적으로 suspend 상태로 생성되므로, resume()을 해주어야 시작된다
많은 App들이 이미지,문서같은 파일을 업로드할 수 있는 서버와 작업하게 되며, JSON같은 구조화된 data를 허용하는 웹서비스 API endpoint를 사용합니다. App에서 서버로 data를 업로드하기 위해 URLSession을 사용하여 URLSessionUploadTask
인스턴스를 생성하게 됩니다. 이 업로드 Task는 URLRequest 인스턴스에 설정된 업로드가 어떻게 수행되어야할지에 대한 세부사항을 사용합니다
업로드할 data는 파일, 스트림, 데이터의 content가 될 수 있습니다. 참고로, 많은 웹서비스 endpoint들이 JSON 포맷을 사용하고 있습니다
data 인스턴스를 만드는 다른 많은 방법이 존재합니다. 예로, 이미지를 JPEG/PNG로 인코딩한 data라던지, string을 UTF-8로 인코딩한 data라던지 등.
업로드 Task는 URLRequest
인스턴스를 필요로 합니다. URLRequest의 httpMethod
를 (서버의 요구사항에 따라) "POST" 혹은 "PUT"으로 설정합니다. HTTP 헤더는 setValue(_:forHTTPHeaderField:)
메서드로 설정합니다. 단, Content-Length
는 session이 data 크기를 참고하여 자동으로 알아내므로 설정하지 않아도 됩니다
let url = URL(string: "https://example.com/post")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
업로드를 시작하기 위해 URLSession의 uploadTask(with:from:completionHandler:)
메서드를 호출하여 URLSessionTask
인스턴스를 생성합니다 (메서드 파라미터로 URLRequest와 Data 전달). Task는 suspend 상태로 시작하므로 resume()
을 호출하여 업로드를 시작합니다
let task = URLSession.shared.uploadTask(with: request, from: uploadData) { data, response, error in
if let error = error {
print ("error: \(error)")
return
}
guard let response = response as? HTTPURLResponse,
(200...299).contains(response.statusCode) else {
print ("server error")
return
}
if let mimeType = response.mimeType,
mimeType == "application/json",
let data = data,
let dataString = String(data: data, encoding: .utf8) {
print ("got data: \(dataString)")
}
}
task.resume()
업로드 Task 역시 completion handler 대신 delegate를 사용할 수 있습니다. URLSessionDelegate
와 URLSessionTaskDelegate
프로토콜을 준수하는 delegate를 구현하고, completion handler를 파라미터로 받지 않는 uploadTask(with:from:)
메서드를 호출합니다