URLSession 이란?
주어진 URL 이 가리키는 endPoint 로부터 자료를 다운로드 받거나 업로드 할 수 있는 API 를 제공하는 클래스이다.
URLSession / URLSessionTask / URLSessionConfiguration ?
URLSession 에서 가장 중요한 세가지 객체를 이해하고 넘어가보자.
URLSession 객체를 사용하여 하나 이상의 URLSessionTask 객체를 생성할 수 있는데,
이러한 URLSessionTask 는 데이터를 Fetch 하여 앱으로 데이터를 전달하거나, 파일을 다운받거나, 원격 장소에 데이터나 파일을 업로드하는 일을 의미한다.
이러한 Session 을 구성하기 위하여 URLSessionConfiguration 객체를 사용하는데, 이 객체는 Cache 나 Cookie 의 사용 방법이나 셀룰러 네트워크 에서 연결을 허용할지 여부와 같은 동작을 제공한다.
URLSession LifeCycle
날씨 데이터를 가져오는 과정을 통해 URLSession LifeCycle 을 정리해본다.
① Session Configuration 을 결정하고, Session 을 생성
let session = URLSession(configuration: .default)
② 통신할 URL 과 Request 객체를 설정
guard let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=\(cityName)&appid=5ac23cbb5dc7e5ff34c5f749077eaa8b") else { return }
## Request 객체는 언제 생성할까?
open RESTFul API 를 사용 시 토큰이 필요할 때가 있다.
토큰이란 인증된 사용자만이 API 를 통해 데이터를 주고 받을 수 있도록 발급한 것인데, 해당 토큰을 헤더에 넣어서 Request 하는 경우가 있다. 이와 같은 경우 URLRequest 를 사용한다.
다음은 어느 API 를 사용하기 위해 인증된 토큰을 헤더에 넣은 예제이다. (날씨 API X)
let param = "전달할 파라미터"
let paramData = param.data(using: .utf8)
let dataURL = URL(string: "호출할 API 주소")
let cliendID = "뭐시기뭐시기"
let clientSecret = "뭐시기뭐시기"
var request = URLRequest(url: dataURL!)
request.httpMethod = "POST"
request.addValue(clientID, forHTTPHeaderField: "ClientID 를 담을 필드")
request.addValue(clientSecret, forHTTPHeaderField: "ClientSecret 를 담을 필드")
request.httpBody = paramData
request.setValue(String(paramData!.count), forHTTPHeaderField: "Content-Length")
③ 사용할 Task 를 결정하고, 그에 맞는 Completion Handler 나 Delegate 메서드들을 작성
dataTask 가 API를 호출하고 서버에서 응답이 오면 completionHandler 클로저가 호출된다.
!! completionHandler 호출
→ data : 서버에서 전달된 데이터
→ response : HTTP Header, Status Code 저장
→ error : 요청 실패 시, 요청이 성공하면 error == nil
!! [weak self] 처리해주는 이유
completionHandler 클로저 안에서 API 비동기 데이터 처리로 인해 지연 할당이 발생할 수 있기 때문이다.
!! JSON 데이터가 디코딩 되는 라인에 옵셔널 바인딩 처리하는 이유
선언한 decoder 와 JSON 데이터를 매핑시켜줄 Codable 프로토콜을 준수하는 사용자 정의 타입을 통해 디코딩 작업을 수행하나, 잘못 정의된 사용자 정의 타입에 의해 정상적인 디코딩이 수행되지 않을 수 있으므로 옵셔널 바인딩 처리한다.
# Codable 프로토콜을 준수하는 사용자 정의 타입...?
https://younngjun.tistory.com/30
!! UI 업데이트 시 Main Thread 에서 수행되도록 처리하는 이유
네트워크 작업은 별도의 스레드에서 진행되고, 응답이 된다 하여도 자동으로 메인 스레드로 돌아오지 않기 때문에, completionHandler 클로저에서 UI 작업을 한다면 main 스레드에서 작업을 할 수 있도록 해야한다.
session.dataTask(with: url) { [weak self] data, response, error in
// 에러 처리를 위한 상수 정의
let successRange = (200..<300)
// 요청 성공/실패 여부
guard let data = data, error == nil else { return }
// JSONDecoder: JSON 객체에서 데이터 유형의 인스턴스로 Decoding 하는 객체
// Decodable, Codable 프로토콜을 준수하는 사용자 정의 타입으로 변환
let decoder = JSONDecoder()
if let response = response as? HTTPURLResponse, successRange.contains(response.statusCode) {
// Parameter 1: JSON을 매핑시켜줄 Codable 프로토콜을 준수하는 사용자 정의 타입 대입
// Parameter 2: 서버에서 응답받는 JSON Data (== data)
guard let weatherInformation = try? decoder.decode(WeatherInformation.self, from: data) else { return }
DispatchQueue.main.async {
self?.weatherStackView.isHidden = false
self?.configureView(weatherInformation: weatherInformation)
}
} else {
guard let errorMessage = try? decoder.decode(ErrorMessage.self, from: data) else { return }
DispatchQueue.main.async {
self?.showAlert(message: errorMessage.message)
}
// debugPrint(errorMessage)
}
}.resume()
}
④ 해당 Task 실행
.resume() // task 메서드.resume() : 작업 실행
⑤ Task 완료 후 Completion Handler 클로저 호출
⑥ 클로저 안에서 작업에 대한 결과값을 반환
URLSession 구성
1) 공유 세션(Shared Session) - URLSession.shared()
간단한 몇줄의 코드로 구현하여 URL 의 contents 에서 데이터를 받아오는 경우 shared 를 사용해도 된다.
이미 Singleton 으로 하나의 객체밖에 없으므로, 직접 생성하는 것이 아닌 단지 접근하여 사용한다.
그러므로 delegate 나 configuration 객체를 사용할 수 없다.
2) 기본 세션(Default Session) - URLSession(configuration: .default)
① 공유 세션과 유사하게 작동하지만 직접 원하는 설정을 할 수 있다.
② 캐시와 쿠키 인증을 디스크에 저장한다. (Disk Caching 지원)
③ 순차적으로 데이터를 처리하기위해 delegate 를 지정할 수 있다.
3) 임시 세션(Ephemeral Session) - URLSession(configuration: .ephemeral)
① 공유 세션과 유사하지만, 캐시, 쿠키, 사용자 인증 정보를 메모리에 저장하지 않는다.
② 메모리에 올려서 session을 연결하고, session 만료 시 데이터가 사라진다
4) 백그라운드 세션(Background Session) - URLSession(configuration: .background)
① 앱이 실행되지 않는 동안, 백그라운드에서 컨텐츠 업로드 및 다운로드 수행할 수 있다.
URL SessionTask 를 활용한 Session 내 작업 추가
1) URLSessionDataTask
① 데이터 객체를 사용하여 데이터를 요청하고 응답받는다
② 주로 짧고 빈번하게 요청하는데 사용
2) URLSessionUploadTask
① 데이터 객체 또는 파일 형태의 데이터를 업로드하는데 사용
② 앱이 실행되지 않았을 때 Background 업로드를 지원한다
3) URLSessionDownloadTask
① 데이터를 다운로드 받아서 파일 형태로 저장하는데 사용
② 앱이 실행되지 않을 때는 Background 다운로드를 지원한다
4) URLSessionStreamTask
① TCP/IP 연결을 사용할 때 사용
5) URLSessionWebSocketTask
① WebSocket 프로토콜 표준을 통해 통신할 때 사용
' iOS > UIKit' 카테고리의 다른 글
CALayer 와 CAAnimation (0) | 2022.09.23 |
---|---|
resignFirstResponder vs .endEditing (0) | 2022.09.06 |
UICollectionView ContentView / UICollectionViewFlowLayout (0) | 2022.08.11 |
UITableView 를 활용한 ToDoList App 만들기 + Alert (0) | 2022.08.10 |
UIKit 계산기 Storyboard UI (0) | 2022.07.15 |