URLSession

GUNDY·2025년 5월 3일
1

iOS

목록 보기
3/4

Swift로 인터넷 작업을 수행하는 방법에 대한 이야기, 두 번째

첫 번째는 404였어서 이미지 재탕 아님


URLSession

지난 시간과 마찬가지로 URLSession의 모든 부분을 다루지는 않을 것이기 때문에, 공식 문서를 읽으면 좋다.

다 다루면 글이 너무

URLSession

URLSession을 사용해 다음과 같은 일들도 할 수 있다.

  • 연결이 끊어져도 처음부터 다시 시작하지 않고 업로드 일시 중지 및 다시 시작
  • HTTP 기반 네트워크 성능 및 앱 사용량 측정
  • 비동기 연산자 체인을 사용하여 URL에서 가져온 데이터 수신 및 처리
  • 앱이 비활성화되어 있을 때 파일을 다운로드하는 작업 만들기
  • 파일을 파일 시스템에 직접 다운로드

각 작업 수행방법에 대해서는 다루지 않을 것이니까 큰 맥락에서 URLSession을 알아보자

Overview

공식문서의 Note 부분을 살펴보면 다음과 같은 내용이 적혀 있다.

URLSession API는 상당히 복잡한 방식으로 함께 작동하는 여러 클래스로 구성되어 있으며, 참조 문서만 읽어서는 이해하기 어려울 수 있습니다. API를 사용하기 전에 URL 로딩 시스템 항목의 개요를 읽어보세요.

이것이 지난 글을 쓴 이유나 다름없다.
사실 상위 문서라서 먼저 작성한 것은 비밀

아무튼 URLSession 클래스와 관련 클래스는 URL로 지정된 엔드포인트에서 데이터를 다운로드하고 업로드하는 API를 제공한다는 점이 오늘의 핵심이다.

앱은 하나 이상의URLSession 인스턴스를 생성한다.

지난 시간에도 이야기 했듯이 여러개를 사용하는 경우도 있다.

예를 들어 웹 브라우저를 만드는 경우, 앱은 탭이나 창당 하나의 세션을 생성하거나, 대화형 사용을 위한 세션 하나와 백그라운드 다운로드를 위한 세션 하나를 생성할 수 있습니다.

복기를 위한 재탕 이미지

앱은 각 세션에 작업을 추가하고, 각 작업은 특정 URL에 대한 요청을 나타낸다.

세션 유형

지난 시간에 언급했듯이 URLSessionshared라는 클래스 프로퍼티를 제공한다.

shared 세션의 경우는 커스텀이 불가능하기 때문에 아주 제한적인 기본 요청에 대해서 사용하기 좋다.

그 밖에는 세 가지 유형의 세션이 있다.

  1. 기본 세션: shared 싱글톤 객체랑 비슷한데, 커스텀이 가능하다는 점이 다르다.
  2. 임시 세션: 디스크에 캐시, 쿠키 또는 자격 증명을 기록하지 않는다.
  3. 백그라운드 세션: 앱이 실행 중이 아닐 때 백그라운드에서 콘텐츠를 업로드하고 다운로드할 수 있다.

그래서 세션을 구성하는 URLSessionConfiguration 문서를 보면 객체를 만드는 방법이 다음과 같이 나와있다.

Deprecated
Use default or other class methods to create instances.

init이나 new와 같이 URLSessionConfiguration의 새로운 인스턴스를 만드는 방식은 이제 애플의 눈 밖에 났다.

앞으론 세 개만 써!

URLSessionTask

URLSession의 API가 제공하는 대표적인 작업 유형은 4가지가 있다.

  • 데이터 작업
  • 업로드 작업
  • 다운로드 작업
  • WebSocket 작업

그래서 세션에 각 작업을 추가하는 메서드의 이름도 직관적이다.

func dataTask(with: URL) -> URLSessionDataTask

func downloadTask(with: URL) -> URLSessionDownloadTask

func webSocketTask(with: URL) -> URLSessionWebSocketTask

각 작업추가 메서드는 URLSessionDataTask, URLSessionDownloadTaskURLSessionTask를 상속받는 구체 타입의 인스턴스를 반환한다.

기본적으로 URL을 통해 각 URLSessionTask를 만들 수 있지만 그 밖에도 completionHandler를 전달하거나 URL 대신 URLRequest를 전달하는 등의 오버로드 바리에이션이 있다.

업로드 작업의 경우는 이 URLRequest를 반드시 필요로 한다.

이 밖에도 URLSessionStreamTask를 반환하는 streamTask라는 메서드도 있다.

만약 작업 자체에 디테일한 커스터마이즈가 필요하다면 URLSessionTask의 서브클래스를 만들고, URLSession에 작업 추가 메서드를 만들어 쓰면 되지 않을까?

뭐 나는 그런 적 없긴 하지만


여기까지 해서 URL Loading System의 기본적인 네트워크 송수신 작업 매커니즘을 알아봤다.

그런데 코드가 없으면 약간 심심하잖여?

그래서 준비해봤다.

URLSession 샘플 코드

이 글을 읽는 사람이 URLSession에 대해 아주 잘 알 거라고는 생각하지 않는다.

그래서 최대한 간단한 예시를 들어보려고 했는데, 아무래도 시각적으로 보이는 게 없으면 딱 와닿지 않을 것 같아서 약간 iOS를 섞어보겠다.

간단히 이미지 교체 버튼이 눌리면 이미지를 바꿀 것이다. 버튼이 눌리면 호출될 메서드 이름은 changeImage로 하겠다.

private func changeImage() { // 버튼이 눌리면 호출
    guard let url = URL(string: "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcT4nBTHRMzJv2Aw6UVVfaoRlf0j6vlMCsYZ1Q&s") else { // 가져올 이미지의 URL
        return
    }
    
    let session = URLSession.shared // URLSession 인스턴스
    let task = session.dataTask(with: url) { data, response, error in // completionHandler
        if let data, // 작업 수행 결과 전달된 데이터
           let image = UIImage(data: data) {
            DispatchQueue.main.async {
                self.imageView.image = image // 이미지를 새로 받아온 이미지로 변경
            }
        }
    } // 작업을 만드는 코드
    
    task.resume() // 작업을 시작하는 코드
}

나중에 해당 URL이 변경될 수 있으니 혹시 궁금하신 분들은 저마다의 이미지 주소를 사용해보길.

추가된 작업은 resume 메서드를 호출하는 것으로 작업을 시작할 수 있다.

동작 예시


마무리

URLSession에 관련된 타입은 무척 다양한데, 모든 타입을 블로그에서 다룰 생각은 아직은 없다.

아마 오늘 나왔던 URLRequest 정도 다루지 않을까?

블로그에는 되도록이면 초심자도 이해할 수 있는 간단한 내용 위주로 포스팅하고 싶다. 핵심 개념만 이해하면 디테일한 커스텀 정도는 스스로 할 수 있다고 생각하기 때문이다.

그 말은 즉

딥 다이브는 여러분의 몫

profile
개발자할건디?

0개의 댓글