본문은 야곰 아카데미 커리어 스타터 캠프를 통해 학습한 내용을 회고한 글입니다.
Overview
remote 서버와 작은 상호작용의 경우, 응답 데이터를 메모리로 받아오기 위해서 URLSessionDataTask 클래스를 사용할 수 있다. (데이터를 직접적으로 파일 시스템에 저장하는 URLSessionDownloadTask 클래스를 사용하는 경우와 반대로) 데이터 작업은 웹 서비스 endpoint를 호출하는 것과 같은 용도에 이상적이다.
URL 세션 인스턴스를 사용해서 작업을 생성할 수 있다. 만약 요구사항이 간단하다면, URLSession 클래스의 shared 인스턴스를 사용할 수 있다. 만약 델리게이트 콜백을 통한 전송과 상호작용하려면, shared 인스턴스를 사용하는 대신에 세션 하나를 만들어야할 것이다. 세션을 만들 때는 URLSessionConfiguration 인스턴스를 사용한다. 또한 URLSessionDelegate나 하위 프로토콜 중 하나를 구현하는 클래스를 전달한다. 세션은 여러개의 작업을 생성하기 위해 재사용 될 수 있으므로, 필요한 각각의 고유 구성에 대해서, 세션을 생성하고 프로퍼티로 저장한다.
<aside> 💡 필요한 것 이상으로 많은 세션을 만들지 않도록 주의하라. 예를 들어서, 앱의 여러부분에서 유사하게 구성된 세션을 필요로 하는 경우, 하나의 세션을 생성하여 공유한다.
</aside>
세션이 있으면 dataTask() 메서드 중 하나를 이용하여 데이터 작업을 생성한다. 작업들은 일시 중단된 상태로 생성이 되며, resume()를 호출해서 시작할 수 있다.
Receive Results with Completion Handler
데이터를 받아오는 가장 간편한 방법은 completion handler를 사용하는 데이터 작업을 생성하는 것이다. 이러한 처리를 통해서, 그 작업은 서버의 response, data 그리고 error를 제공된 completion handler 블록에 넘겨준다. Figure 1은 세션과 작업과의 관계에 대해서 보여주고 있으며, 어떻게 결과가 completion handler에 전달되는지역시 보여주고 있다.
Figure 1 Creating a completion handler to receive results from a task
completion handler를 사용하는 데이터 작업을 생성하기 위해서는, URLSession의 dataTask(with:) 메서드를 사용하라. 그리고 completion handler는 다음의 세 가지 작업을 수행해야한다:
- error 매개변수가 nil이라는 것을 검증한다. 그렇지 않으면, error가 발생했다는 것을 전달한다; error를 처리하고 빠져나간다.
- status code가 성공을 가리키고 MIME type이 예상된 값이라는 것을 검증하기 위해서 response 매개변수를 확인한다. 그렇지 않다면, 서버 error를 처리하고 빠져나간다.
- 필요에 따라서 data 인스턴스를 사용한다.
Listing 1은 URL의 내용을 가져오는 startLoad() 메서드를 보여주고 있다. 이 과정은 결과값을 completion handler로 전달하는 데이터 작업을 만들기 위해 URLSession 클래스의 shared 인스턴스를 사용하는 것으로 시작한다. 로컬과 서버의 error를 확인한 후, 이 handler는 data를 String으로 변환한다, 그리고 그것을 WKWebView outlet을 생성하기 위해 사용한다. 당연하게도, 앱에서 가져온 데이터를 데이터 모델로 파싱하는 것과 같이 다른 용도로 사용할 수도 있다.
Listing 1 Creating a completion handler to receive data-loading results
func startLoad() {
let url = URL(string: "<https://www.example.com/>")!
let task = URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
self.handleClientError(error)
return
}
guard let httpResponse = response as? HTTPURLResponse,
(200...299).contains(httpResponse.statusCode) else {
self.handleServerError(response)
return
}
if let mimeType = httpResponse.mimeType, mimeType == "text/html",
let data = data,
let string = String(data: data, encoding: .utf8) {
DispatchQueue.main.async {
self.webView.loadHTMLString(string, baseURL: url)
}
}
}
task.resume()
}
💡 completion handler는 작업을 생성한 것과 다른 Grand Central Dispatch queue에서 호출된다. 그렇기때문에, UI를 업데이트하기 위해 data나 error를 사용하는 어떠한 작업이라도 (webView를 업데이트하는 것과 같은) 여기에 표시된 것처럼 명시적으로 main queue에 위치해야한다.
'YAGOM CAREER STARTER' 카테고리의 다른 글
[TIL] 20230330: Escaping closure/Defer (0) | 2023.04.04 |
---|---|
[TIL] 20230327: class/struct, 네트워크 통신 없이 Test하는 이유 (0) | 2023.03.28 |
[TIL] 20230317: Responder Chain / Touch Event (0) | 2023.03.18 |
[CODE STARTER 복습] 20230317: week01 (0) | 2023.03.17 |
[TIL] 20230314: wait()/notify(queue:) (0) | 2023.03.14 |