URL(Uniform Resource Locator)은 특정 유형의 URI(Universal Resource Identifier)로, 웹 클라이언트가 서버에 리소스를 요청할 때 사용된다.
URI는 리소스를 식별하는 문자열로 정의되고, URL은 리소스의 위치 또는 리소스에 접근하는 데 사용되는 수단으로 리소스를 식별하는 URI로 정의된다.
즉, URI는 특정 리소스 식별자이고 URL은 특정 리소스 위치를 뜻하기 때문에 URI 방법 중 하나가 URL이다.
HTTP용 URL은 3~4개의 구성 요소로 이루어져 있다.
- scheme : 인터넷에서 리소스에 접근하는 데 사용할 프로토콜을 식별한다. (HTTP나 HTTPS)
→ 프로토콜 : 컴퓨터 내부 혹은 사이에서 데이터의 교환 방식을 정의한 규칙 체계로, 서버에 접속할 때 어떤 방식으로 통신할 지 정의한다. HTTP와 HTTPS가 해당된다.
→ HTTP 통신은 웹서버 통신 중 하나로 URL 기반으로 클라이언트에서 요청을 보내고, 서버로부터 응답을 받는 형태의 통신이다.- host : 호스트 이름은 리소스를 보유한 호스트를 식별한다. 예를 들어, www.example.com 호스트 이름 뒤에 포트 번호가 올 수도 있는데, 대부분의 서버는 잘알려진 포트 번호를 사용하기 때문에 생략된다.
→ 포트 : 한 개의 컴퓨터에는 여러 개의 서버가 존재할 수 있는데, 포트 번호를 통해 어떤 서버를 이용할 지 결정한다.- path : 컴퓨터 내부에 있는 디렉토리의 파일을 가리키며, 리소스의 경로를 의미한다.
- query string : 특정 목적에 사용할 수 있는 정보 문자열을 제공하며, 쿼리 문자열은 일반적으로 이름과 값 쌍의 문자열이다.

표준 인터넷 프로토콜을 사용하여 URL과 상호작용하고 서버와 소통하는 기술로, Foundation 프레임워크에 포함된 기능이다. HTTPS와 같은 표준 프로토콜 또는 사용자 정의 프로토콜을 사용하여 URL로 식별되는 리소스에 대한 액세스를 제공한다. Loading은 비동기로 수행되기 때문에 앱이 데이터를 주고받는 작업을 하면서도 계속 사용자와 상호작용 할 수 있다.
URLSession은 URL을 통해 특정되는 엔드포인트에서 데이터를 다운로드하고 엔드포인트로 데이터를 업로드하기 위한 API를 제공하며, 네트워크 통신과 관련된 작업들의 그룹을 관리하는 객체이다.
URLSession 객체에 접근할 수 있는 방법은 두가지로, 싱글톤 인스턴스인 shared와 이니셜라이저이다. shared session을 사용하면 delegate나 configuration을 제공하지 않기 때문에 기본적인 데이터 전송만을 지원하고, 이니셜라이저를 통해 접근하면 URLSessionConfiguration을 통해 커스터마이징이 가능하다.
URLSessionConfiguration은 URLSession의 동작과 정책을 정의할 수 있는데, 시간 제한 값/캐싱 정책/연결 요구 사항 및 URLSession에 사용하려는 기타 유형의 정보를 정의할 수 있다.
→ 추가로, URLSessionConfiguration 객체가 세션에 한번 설정되고 나면 새로운 URLSessionConfiguration이 들어와도 무시된다.
URLSessionTask는 세션 작업 하나를 나타내는 추상 클래스로, Task는 항상 세션의 일부로 존재한다.
URLSession을 통해 하나 이상의 URLSessionTask 인스턴스를 만들 수 있는데, 해당 인스턴스가 통신을 통해 데이터를 받아 앱에 전달하는 역할을 한다. 그리고 하나의 세션을 통해 여러개의 Task를 생성할 수 있다.

Task는 세션의 delegate의 메서드를 호출해서 completion handler에 data/response/error를 반환한다.
Task들은 일시정지 된 상태로 생성되며, resume() 메서드를 호출해서 시작할 수 있다.
URLSession은 HTTP 통신과 마찬가지로 Request와 Response 구조를 가지고 있다.
: 프로토콜이나 URL scheme으로부터 독립적인 URL 로드 요청
URLRequest는 요청에 대한 정보만을 표현하는 객체로 요청을 로딩하기 위해 필수 속성 두가지를 캡슐화하고 있는데, 로딩할 URL과 로딩하는데 사용되는 정책이다. 또한 HTTP와 HTTPS 요청의 경우, HTTP method(GET, POST, …) 및 HTTP header가 포함된다.
HTTP method의 기본 값은 GET이며, String 타입으로 값을 할당해준다.
HTTP header는 addValue() 메서드를 통해 key-value 형태로 헤더 필드에 값을 추가할 수 있다. 참고로 특정 헤더 필드는 예약되어 있기 때문에 해당 메서드를 사용해 예약된 HTTP header 필드를 변경하면 안된다.
URL 로드 요청에 대한 응답과 관련된 메타데이터로, URLResponse 객체에는 URL의 콘텐츠를 나타내는 실제 바이트가 포함되어 있지 않다.
URL을 파싱하여 부분적으로 URL을 구성하는 구조로, URLComponents 값의 내용을 기반으로 URL 값을 쉽게 얻을 수 있으며 반대로 구성 부분들의 값들도 얻을 수 있다.
URL의 쿼리 부분에서 나온 단일 key-value 쌍으로, URLComponents의 URLQueryItems에 값을 할당하여 쿼리 문자열을 설정할 수 있다.
각 세션은 주기적인 업데이트 또는 오류를 받기 위해 델리게이트와 연결된다. 기본적으로 completion handler 블록을 호출하며, 사용자 정의 델리게이트를 제공하도록 선택하면 해당 블록은 호출되지 않는다.

Task의 활동에 더 높은 수준의 접근을 원한다면 Data Task를 만들 때 completion handler를 제공하는 대신 세션에 delegate를 설정할 수 있다.

delegate를 사용하면 전송이 완료되거나 오류로 실패할 때까지 데이터의 일부가 도착하는 대로 URLSessionDataDelegate의 urlSession(_:dataTask:didReceive:) 메서드에서 반환해줍니다. Delegate는 전송이 진행됨에 따라 다른 종류의 이벤트도 수신한다.
그리고 Delegate 방식으로 접근하기 위해서는 shared 인스턴스가 아닌, URLSession 인스턴스를 생성해줘야 하고 생성할 때 delegate를 채택한 객체를 지정해줘야 한다.
Delegate 방식으로 접근하는 경우 좋은 configuration 설정이 있는데, URLConfiguration의 waitsForConnetivity 값을 true로 설정해주는 것이다. 네트워크는 여러 가지 이유에 의해 일시적으로 연결이 불가능할 수 있는데, 이때 해당 속성의 값이 true라면 세션은 즉시 작업을 실행하여 delegate의 메서드에서 콜백이 실패를 반환하게 하지 않고 적절한 연결이 될 때까지 기다린다.
→ 참고로, 해당 속성은 항상 연결을 기다리는 백그라운드 세션에서는 무시된다.
URLSessionDelegate 프로토콜에 정의된 메서드 외에도 대부분의 delegate는 작업 수준 이벤트를 처리하기 위해 URLSessionTaskDelegate, URLSessionDataDelegate 및 URLSessionDownloadDelegate 프로토콜의 메서드 중 일부 또는 전부를 구현해야 한다.
만약 URLSession 객체에 delegate를 할당하지 않은 경우, 시스템에서 제공하는 delegate가 사용되며 데이터를 가져오려면 completion handler를 통해 가져와야 한다.
세션 객체는 앱이 종료되거나 세션을 명시적으로 무효화할 때까지 delegate에 대한 강한 참조를 유지하기 때문에 세션을 무효화하지 않으면 앱이 종료될 때까지 메모리가 누수된다.
대부분의 네트워킹 API와 마찬가지로 URLSession API 또한 매우 비동기적이다. URLSession에 정의된 비동기 메서드를 호출할 때 await 키워드를 사용하여 전송이 완료될 때까지 실행을 일시 중단한다.
URL Loading System | Apple Developer Documentation
Fetching Website Data into Memory | Apple Developer Documentation
URLSession | Apple Developer Documentation