본문 바로가기

Swift

URLSession (개념)

728x90

URLSession

데이터를 다운로드 하거나 업로드 하는 등의 API를 제공해주는 클래스로 URL이 가리키는 End Point를 갖고 있다.

 

URLSession API를 통해서 데이터를 어떻게 전송하고 어떻게 동작할 지 등의 정책을 설정할 수 있다. 

> 타임 아웃, 캐시 정책, 백그라운드 데이터 전송 

 

간단하고 기본적인 요청인 경우에는 동작과 전송에 대한 정책이 기본적으로 설정되어 있는 Shared Session을 사용할 수도 있고, 별도 처리를 하기 위해서는 Session Configuration 객체를 통해 Session을 생성할 수 있다.

> Session Configuration 객체를 통해서 Default Session, Ephemeral Session, Background Session 등을 생성할 수 있다.

 

URLSessionConfiguration

URLSession을 통해서 데이터를 다운로드하거나 업로드 할 때, URLSessionConfiguration을 통해 세부적인 동작과 정책을 설정할 수 있다.

 

URLSessionConfiguration에서는 일반적인 프로퍼티 설정, 쿠키 정책, 보안 정책, 캐시 정책, 백그라운드 전송 등을 세부적으로 설정할 수 있다.

  • 일반적인 프로퍼티
    셀룰러 연결 여부 (와이파이<->셀룰러 변경 시), 타임 아웃 간격, 리소스 요청 최대 시간 등
  • 캐시 정책 
    캐시 활성화/비활성화 여부, 캐시 만료 기간. 마지막 요청 이후 컨텐츠 변경 확인 등 
  • Background Session 기본값은 nil, Ephemeral Session의 기본값은 메모리에만 데이터를 저장한다.

 

Shared Session

  • 싱글턴 패턴 구조로 기본 설정이 되어 있어 단순한 네트워크 요청을 할 때 주로 사용이 되고, 커스터마이징은 할 수 없다.
  • 네트워크 응답에 대해서는 Completion Handler를 통해서 전달받게 된다.
  • 구현이 간단하지만 백그라운드 전송은 지원하지 않는다. 

 

Default Session

  • URLSessionConfiguration을 통해 직접 생성하는 세션으로 Shared Session과 기본 설정이 유사하게 되어 있다. 다른점은 커스터마이징이 가능하다.
  • 네트워크 응답에 대해서는 Delegate를 통해 세부적인 제어가 가능하다. 

 

Default Session

  • URLSessionConfiguration을 통해 직접 생성하는 세션으로 앱이 실행 중이지 않을 때나 백그라운 상태에서도 데이터를 다운로드 하거나 업로드 할 수 있다.

 

URLSessionTask

세션이 생성된 이후에는 Task를 생성하게 되는데 URLSession을 통해 생성되는 개별 요청이 Task이다.

 

데이터를 전달하는 방식과 구현하려는 목적에 따라서 Task 타입이 존재한다.

  • DataTask
  • UploadTask
  • DownloadTask
  • StreamTask

 

Task는 suspended 상태로 시작하기 때문에 Task를 생성한 이후에는 resume 메서드를 통해 Task를 시작할 수 있고 따라서 resume을 호출해야 네트워크 통신을 시작할 수 있다. 

 

URLRequest

네트워크 요청에 대한 정보를 표현하는 객체

 

- 어떤 HTTP Method가 사용되는지

- 어떤 데이터를 전송하는 것인지 

등의 정보를 담고 있으며 네트워크에 요청을 하기 위해서는 URLSession이 필요하다.

 

URL객체를 통해 통신하거나 URLRequest 객체를 통해 세부 옵션(캐싱, HTTP Method 등)에 대한 옵션을 설정할 수 있다.

 

import Foundation

enum HttpMethod: String {
    case GET
    case POST
    case PUT
    case PATCH
    case DELETE
}

struct NetworkRequest {
    let url: String
    let headers: [String: String]?
    let body: Data?
    let requestTimeOut: Float?
    let httpMethod: HttpMethod
    
    init(url: String,
         headers: [String: String]? = nil,
         reqBody: Data? = nil,
         reqTimeout: Float? = nil,
         httpMethod: HttpMethod
    ) {
        self.url = url
        self.headers = headers
        self.body = reqBody
        self.requestTimeOut = reqTimeout
        self.httpMethod = httpMethod
    }
    
    func buildURLRequest(with url: URL) -> URLRequest {
        var urlRequest = URLRequest(url: url)
        urlRequest.httpMethod = httpMethod.rawValue
        urlRequest.allHTTPHeaderFields = headers ?? [:]
        urlRequest.httpBody = body
        return urlRequest
    }
}

위의 코드처럼 헤더 정보, 요청데이터, HTTP 메서드 등을 설정할 수 있다.

 

URLResponse

프로토콜 및 URL 스키마와 관계 없이 URL 로드 요청에 대한 응답과 관련된 메타데이터이다.

 

URLResponse 객체는 실제로 HTTP URLResponse 클래스의 인스턴스이고,

HTTL URLResponse는 URLResponse의 서브 클래스이다.

 

URLResponse를 그대로 콘솔에 찍어보면 아래와 같다.

 

이렇게 서버로부터 응답을 받은 데이터를 처리할 수 있는 방법은 Completion Handler 또는 Session Delegate를 활용하는 두가지 방법이 있다.

 

Completion Handler

Task에 대한 completion handler 형태로 응답을 받을 수 있고,

이는 task가 종료되고 난 시점에 한 번만 호출이 된다.

 

서버로부터 전달 받은 data와 HTTP Header, 응답에 대한 메타데이터 등의 정보가 들어있는 response, 요청이 실패했을 때에 대한 error 값을 전달받을 수 있다.

 

Session Delegate

Task가 실행되는 동안 발생할 수 있는 다양한 상황에 대해서 세부적으로 처리를 하고자 할 때 사용한다. 

 

서버로부터 최초로 응답을 받았을 때

서버로부터 데이터를 받을 때마다 데이터를 받을 때마다

데이터 전송을 다 받은 시점 

.. 등에 대한 이벤트 처리가 가능하다. 

 

 

'Swift' 카테고리의 다른 글

[Swift] static을 언제 쓰는데?  (1) 2022.10.12
[Swift] class func VS static func  (0) 2022.10.12
Codable  (0) 2022.08.31
Type Casting Up? Down?  (2) 2022.08.19
Framework (Dynamic VS Static)  (1) 2022.08.19