[Apple] URLSession

J.Noma·2022년 1월 3일
0

iOS : 네트워킹

목록 보기
6/6

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)

⚙️ Overview

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를 나타냅니다


⚙️ Types of URL Sessions

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을 참고합니다


⚙️ Types of URL Session Tasks

단일 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로 메시지를 교환합니다


⚙️ Using a Session Delegate

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을 가로챌 수도 있습니다


⚙️ Asynchronicity and URL Sessions

대부분의 네트워크 API들처럼, URLSession API도 매우 비동기적입니다. 이것은 3가지 방식으로 data를 반환하며, 각 방식은 당신이 호출하는 메서드에 따라 다릅니다

  1. 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하기 위한 편리한 메서드들을 제공합니다

  2. Completion handler
    Swift/Objc 모두에서, completion handler block을 제공하여 data 전송이 완료될 때 실행되도록 할 수 있습니다

  3. Delegate
    Swift/Objc 모두에서, data 전송이 진행 중일 때나 완료 직후에 delegate 메서드로 오는 callback을 받을 수 있습니다

이 정보들을 delegate로 보내는 것 외에도, URLSession은 status와 progress 프로퍼티를 제공합니다. 만약 task의 현재 상태에 따라 코드 상 분기가 필요하다면 이 프로퍼티들을 사용합니다 (참고로, 이런 status는 언제든 변할 수 있다는 점에 유의합니다)


⚙️ Protocol Support

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 지원을 추가할 수도 있습니다


⚙️ App Transport Security (ATS)

iOS 9.0과 macOS 10.11 부터는 URLSession으로 만들어진 모든 HTTP 연결에 대해 ATS를 사용합니다. ATS는 HTTP 연결이 HTTPS(RFC 2818)를 사용하기를 요구합니다. 자세한 정보는 NSAppTransportSecurity를 참고합니다


⚙️ Foundation Copying Behavior

Session과 Task와 달리, configuration는 NSCopying 프로토콜을 준수합니다

  • App이 단일 session/task 객체를 복사하면, 동일한 객체를 돌려받습니다 (복사안됨)

  • configuration 객체를 복사하면, 새로운 copy를 얻을 수 있습니다 (복사됨)


⚙️ Thread Safety

URL session API는 thread-safe합니다. 그러므로 어떠한 thread context 내에서도 당신은 자유롭게 session과 task를 생성할 수 있습니다. delegate 메서드가 completion handler를 호출할 때, 그 작업은 자동으로 적절한 delegate 큐로 스케줄링됩니다

profile
노션으로 이사갑니다 https://tungsten-run-778.notion.site/Study-Archive-98e51c3793684d428070695d5722d1fe

0개의 댓글