Reference
내용전반: URLSession
✅ Remind
- Session에는 4가지 타입이 있다
(shared, default, ephemeral, background)- Session Task에는 4가지 타입이 있다
(Data, Upload, Download, WebSocket)- Delegate를 사용하면 Task 진행과 관련한 각종 event를 수신할 수 있다
- Session은 Delegate를 강한참조한다
(delegate 객체를 메모리 해제하려면 Session.delegate도 해제해야 한다)- Swift의 async/await 문법을 사용하려면 사용되는 session 메서드가 다르다
- URLSession의 API들은 Thread-safe하게 수행된다
- URLSessionConfiguration은 완전복사가 가능하다 (NSCopying)
URLSession class, 그리고 그와 관련된 class들은 URL이 가리키는 endpoint로부터 data를 다운로드받고 업로드하는 API를 제공합니다. 또한, App이 running 혹은 suspend일 때, 백그라운드에서 다운로드를 수행하기 위해 이 API를 사용할 수도 있습니다. 인증 작업을 서포트하고 redirection 혹은 task 완료 같은 event를 수신하기 위해 URLSessionDelegate
, URLSessionTaskDelegate
를 사용할 수 있습니다
✅ NOTE
URLSession API는 많은 서로 다른 class들을 포함하는데 이 class들은 상당히 복잡한 방식으로 함께 동작합니다. 참조문서를 읽을 경우 명확하지 않을 수 있습니다. API를 사용하기 전에 URL Loading System의 개요를 읽어보라. 그리고, Essentials,Uploading,Downloading 섹션에서 URLSession을 사용한 일반적인 작업의 예제가 제공됩니다
당신의 App은 하나 이상의 URLSession 인스턴스를 만들고, 각 인스턴스는 서로 연관된 data 전송 작업들의 그룹을 조직하게 됩니다. 예로, 당신이 웹브라우저를 만들고 있다면, 당신의 App은 백그라운드 다운로드를 위해 탭,윈도우 등의 것들 하나 당 session 한개를 만들 것입니다. 각 session 내에서, 당신의 App은 task 묶음을 더하게 됩니다. 여기서 각 task는 특정 URL에 대한 하나의 request를 나타냅니다
Session Configruation Object
주어진 URLSession 내의 task들은 공동의 session configuration 객체를 공유합니다. 이 객체는 단일 호스트에 대한 최대 동시 연결 개수라던지, 연결이 셀룰러 네트워크를 사용할 수 있는지 등과 같은 "연결"과 관련한 동작들을 정의합니다
shared
: delegate를 지정할 수 없는 간단한 비동기 요청. custom이 제한적입니다
Default
: 기본 설정 session. custom 가능
Ephemeral
: delegate를 지정할 수 없음. private session으로 disk에 파일을 저장하지 않음. 사파리/크롬의 시크릿모드 만들 때 활용되고 쿠키같은 세션 정보가 남지 않음
Background
: App을 사용하지 않더라도 (suspend/not running)일 때도, 운영체제 level에서 (background로) 업로드/다운로드를 수행하기 위한 session. 지하철이나 지도 App에서 업데이트된 데이터를 받고 싶은 경우, background session을 만들어놓으면 App이 살아있지 않을 때도 업로드/다운로드가 가능해진다
각 타입 별 configuration에 대해서는 URLSessionConfiguration을 참고합니다
단일 session 내에서, 당신은 data를 서버에 업로드하거나 서버의 파일/메모리 등으로부터 data를 가져오는 task를 만들 수 있습니다
URLSession API는 아래 4가지 타입의 task를 제공합니다. 대부분은 Data Task를 쓰게 될텐데 Upload와 Download Task가 필요한 경우가 있습니다
Data Task
dataTask(with:)
를 사용하여 URLSessionDataTask
인스턴스를 만듭니다. Data Task들은 서버에게 리소스를 요청하고, 서버의 응답을 하나 이상의 NSData 객체로 반환하여 메모리로 불러옵니다. session 종류 중 default, ephemeral, shared는 이를 지원하지만, background session은 지원하지 않습니다
Upload Task
uploadTask(with:from:)
를 사용하여 URLSessionUploadTask
인스턴스를 만듭니다. Upload Task는 Data Task와 유사하지만, request body를 제공하기 용이하다는 차이점이 있습니다. 이를 통해 서버의 응답을 찾아오기 전에 Data를 업로드할 수 있습니다. 추가로, Upload Task는 background session에서도 지원됩니다
Download Task
downloadTask(with:)
를 사용하여 URLSessionDownloadTask
인스턴스를 만듭니다. Download Task는 서버의 리소스를 직접 disk에 파일로 저장합니다. Download Task는 모든 session 타입에서 지원됩니다
WebSocket
WebSocket task는 RFC 6455에 정의된 WebSocket 프로토콜을 사용하여, TCP/TLS로 메시지를 교환합니다
delegate
단일 session 내 Task들은 공동의 delegate 객체를 공유합니다. 당신은 delegate를 사용하여 다양한 event가 발생할 때 정보를 제공하거나 얻을 수 있습니다. event에는 인증실패, 서버로부터 Data도착, Data 캐싱이 가능한 상태 등이 있습니다. 만약 delegate가 필요없다면 session을 만들 때 delegate는 nil로 두고 API를 사용하면 됩니다
❗️중요
session 객체는 delegate를 강한 참조하며, 이는 App이 종료되거나 session이 invalidate될 때까지 유지됩니다. 만약 session을 invalidate하지 않는다면, 이로 인해메모리 누수
가 발생합니다
Task는 delegate에게 callback
당신이 session과 함께 만든 각 task는 URLSessionTaskDelegate
에 정의된 메서드들을 통해 session delegate에게 알려집니다(callback). 또한, 이 callback들이 delegate에게 닿기 전에, 해당 task에 특화된 별도의 delegate를 설정하여 callback을 가로챌 수도 있습니다
대부분의 네트워크 API들처럼, URLSession API도 매우 비동기적입니다. 이것은 3가지 방식으로 data를 반환하며, 각 방식은 당신이 호출하는 메서드에 따라 다릅니다
async-await
Swift에서 사용 중이라면, 일반적인 task를 수행하기 위해 aysnc
키워드로 표시된 메서드들을 사용할 수 있습니다. 예로, data(from:delegate:)
는 data를 fetch하고 동시에, download(from:delegate:)
는 파일들을 다운로드합니다. 호출부에서는 await
키워드를 사용하여 data 전송 완료까지 실행을 suspend합니다. 또한, bytes(from:delegate:)
메서드를 사용하여 data를 AsyncSequence
로 받을 수 있습니다. 이런 접근법에서는 App이 data를 받았을 때 이것을 for-await-in
구문으로 iteration할 수 있습니다. 또한, URL
타입은 shared URL session으로부터 bytes와 lines를 fetch하기 위한 편리한 메서드들을 제공합니다
Completion handler
Swift/Objc 모두에서, completion handler block을 제공하여 data 전송이 완료될 때 실행되도록 할 수 있습니다
Delegate
Swift/Objc 모두에서, data 전송이 진행 중일 때나 완료 직후에 delegate 메서드로 오는 callback을 받을 수 있습니다
이 정보들을 delegate로 보내는 것 외에도, URLSession은 status와 progress 프로퍼티를 제공합니다. 만약 task의 현재 상태에 따라 코드 상 분기가 필요하다면 이 프로퍼티들을 사용합니다 (참고로, 이런 status는 언제든 변할 수 있다는 점에 유의합니다)
data, file, ftp, http, https
URLSession class는 기본적으로 data,file,ftp,http,https와 같은 URL scheme을 지원합니다. 또, 유저의 시스템 기본설정에 따라, 프록시 서버와 SOCKS 게이트웨이를 위한 투명한 지원을 제공합니다
HTTP/1.1, HTTP/2, HTTP/3
URLSession은 HTTP/1.1, HTTP/2, HTTP/3 프로토콜을 지원합니다. 그리고, RFC7540에 나와있는 HTTP/2를 지원하려면 ALPN을 지원하는 서버가 있어야 합니다
Custom Protocol/URL scheme
또한, URLProtocol
을 상속함으로써, Custom 네트워크 프로토콜과 URL scheme 지원을 추가할 수도 있습니다
iOS 9.0과 macOS 10.11 부터는 URLSession으로 만들어진 모든 HTTP 연결에 대해 ATS를 사용합니다. ATS는 HTTP 연결이 HTTPS(RFC 2818)를 사용하기를 요구합니다. 자세한 정보는 NSAppTransportSecurity를 참고합니다
Session과 Task와 달리, configuration는 NSCopying
프로토콜을 준수합니다
App이 단일 session/task 객체를 복사하면, 동일한 객체를 돌려받습니다 (복사안됨)
configuration 객체를 복사하면, 새로운 copy를 얻을 수 있습니다 (복사됨)
URL session API는 thread-safe합니다. 그러므로 어떠한 thread context 내에서도 당신은 자유롭게 session과 task를 생성할 수 있습니다. delegate 메서드가 completion handler를 호출할 때, 그 작업은 자동으로 적절한 delegate 큐로 스케줄링됩니다