티스토리 뷰

iOS

[iOS] URLSession 짚어보기

Sueaty 2021. 10. 27. 23:53

URLSession은 네트워크 요청을 통해 데이터를 주고 받을 수 있도록 Apple에서 제공하는 networking API 입니다.

HTTP-/HTTPS-를 베이스로 한 몇 가지 프로토콜을 지원하며 캐시 관리, 인증 그리고 쿠키 관리등도 지원합니다.

일반적으로 URLSession은 다음과 같은 순서로 진행이 됩니다.

 

1. session configuration and create session

2. create task

3. decide usage of completion handler / delgeate method

4. execute/resume task

5. execute completion handler after task completion

 

 

[Session Configuration & Create Session]

URLSession에서 session configuration을 통해 어떤 종류의 session을 생성할 것인지를 결정할 수 있고, 이 외에도 HTTP 헤더나 네트워크 타임아웃 시 어떻게 처리할 것인지 등을 설정할 수 있습니다. 생성할 수 있는 session에는 세 종류가 있어요.

  • default : 기본적인 session으로 디스크 기반 캐싱 지원
  • ephemeral : 메모리에 저장을 하지만 실질적으로는 어떠한 데이터도 저장하지 않는 형태의 session
  • background : 앱이 종류 된 이후에도 background에서 통신을 이어나가는 것을 지원하는 session

 

[Create Session & Task]

열린 Session을 통해 task 단위로 데이터 주고 받는 행위를 하게 되는데요, URLSession API는 총 4종류의 task를 지원합니다.

  • data task : data 객체를 통해 데이터를 주고받는 task
  • upload task : data를 파일의 형태로 전환 후 업로드하는 task
  • download task : data를 파일의 형태로 전환 후 다운 받는 task
  • web socket task

 

이 task들은 종류에 따라 특정 request를 수행할 수 있고(ex. GET, POST 등) 실행되고 있던 task를 중단시키거나 재시작할 수 있기도 합니다. 단, resume이 되기 위해서는 몇몇 조건을 충족시켜야 하니 무조건적으로 되는 것이 아니라는 것 알아두면 좋을 것 같습니다.

 

[Create/Execute Completion Handler / Delegate Method]

URLSession에서 작업이 완료된 후 데이터를 두가지 방법으로 전달하게 되는데요 더 구체적으로 알아보기 위해서는 URLSession의 기본적인 통신 형태를 살펴보는게 좋을 것 같네요.

URLSession의 기본 통신 구조

HTTP 통신처럼 Request, Response 구조를 기본적으로 택하고 있는데 각각 2가지 방식으로 지원합니다.

Response는

  • URL 객체를 통한 직접 통신
  • URLRequest 객체를 통해 옵션 설정 이후 통신

 

Response는

  • completion handler 실행
  • URLSessionDelegate를 통해 저장 된 메소드 호출

이 있습니다.

Request

URL 객체 사용

URL 객체를 통한 직접 통신은 외부에 있는 서버가 아니더라도 디스크 상의 파일을 가리키기도 합니다.

디스크에 저장 된 json 파일을 사용한다던지, 파일을 다운로드한 위치에서 데이터를 가져올 때 주로 사용하죠.

https://www.example.com/ 에 GET 요청을 하면 html 소스를 반환해주는데요, URL 객체를 아래와 같이 생성할 수 있습니다.

let url = URL(string: "https://www.example.com/")!
let task = URLSession.shared.dataTask(with: url) { data, response, error in
   // error 처리
   // 받은 response를 completion handler로 data 전달
}

URLRequest 객체 사용

URLRequest를 통해서 timeout interval, httpMethod, httpBody 등의 옵션을 설정할 수 있습니다.

let request = URLRequest(url: URL(string: "https://www.example.com/")!)
request.timeoutInterval = 30

Response

Completion Handler

final class NetworkService {
   var dataTask: URLSessionDataTask?
   typealias QueryResult = (([Track]?, String) -> Void)
   
   func getSearchResults(url: String, completion: @escaping QueryResult) {
      guard let url = URL(string: url) else { return }
      dataTask = defaultSession.dataTask(with: url) { data, response, error in
         ...
         DispatchQueue.main.async {
         	completion(
         }
      }
      dataTask?.resume(self.tracks, self.errorMessage)
   }
}


final MainViewController: UIViewController {
   ...
   
   func loadTracks() {
      networkService.getSearchResults(url: "...api...") { [weak self] results, errorMsg in
      		// action
      }
   }
}

URLSessionDelegate Method

이 프로토콜에 정의 된 메소드들을 통해 task level의 이벤트들을 처리할 수 있습니다.

대표적으로 background에서 통신을 이어나갈 수 있는 download task를 실행 중이었다면 앱이 종료되었더라도

다운로드를 마치면 특정일들을 수행할 수 있도록 할 수 있습니다. (AppDelegate에서 설정 필요)

이 밖에도 각 task가 시작하는 시점 또는 끝나는 시점의 이벤트를 받아 원하는 일을 수행할 수도 있습니다.

extension MainViewController: URLSessionDelegate {
   func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
      DispatchQueue.main.async {
         if let appDelegate = UIApplication.shared.delegate as? AppDelegate,
            let completionHandler = appDelegate.backgroundSessionCompletionHandler {
               completionHandler()   
         }
      }
   }
}

   

출처

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함