Swift

이제서야 알게된 재미있는 dataTask

kimhyeji 2025. 9. 1. 13:59

URLSession에 대해 톺아보던 중, 재미있는 것을 알게 되어 기록하고자 합니다🙌🏻

 

보통 기본적인 네트워크 통신을 위해서는 아래와 같이 구현을 하지 않을까 싶습니다.

// 1. completion handler
let task = URLSession.shared.dataTask(with: url) { data, response, error in
	if let error {
    	// error 처리
        return
    }
    
    guard let data else { return }
    // data, response 처리
}
task.resume()

// 2. swift concurrency
let (data, response) = try await URLSession.shared.data(from: url)

 

이렇게 서버에 통신을 요청하고 데이터를 받을 때 당연히 하나의 데이터를 받는거니까..라고 생각했는데, 사실은 서버에서 패킷 단위로 데이터를 전달하고 os 상에서 패킷 단위의 데이터들을 스트림 형태로 전달해주면 URLSession 시스템 내부적으로 앱 내부 RAM(버퍼)에 차곡차곡 모아뒀다가 데이터 수신이 끝났을 때 하나의 데이터 객체로 모아 반환하는 방식으로 동작합니다.

 

더보기
더보기

여기에서 자잘한 개념들을 짚고 넘어가자면...

  • 패킷(Packet)
    : 인터넷을 통해 데이터를 주고 받을 때 잘게 나눈 데이터 조각
  • 버퍼(Buffer)
    : 데이터를 옮길 때 잠시 저장해두는 메모리 공간으로, RAM의 일부를 할당받아 사용함

 

그리고 우리는 해당 데이터 패킷을 받을 때마다 알림을 받을 수 있습니다.

바로 URLSessionDataDelegate에 정의된 메서드를 통해 알 수 있습니다. 먼저 메서드 정의를 정리하고 차이를 볼까요?

  • urlSession(_:dataTask:didReceive:completionHandler:)
    : 서버로부터 최초 응답을 받았을 때 호출됩니다.
  • urlSession(_:dataTask:didReceive:)
    : 서버로부터 데이터 조각을 받을 때마다 호출됩니다.
  • urlSession(_:task:didCompleteWithError:)
    : 데이터 수신이 완료되었거나 에러가 발생했을 때 마지막에 한번만 호출됩니다.

최초 응답 호출을 통해 기본적인 응답 정보를 먼저 확인할 수 있습니다. 받게 될 전체 데이터 크기, http 상태코드 등.

이때 completionHandler를 통해 네트워크 요청을 어떻게 처리할지 반환하는 작업이 필요한데, 응답 정보에 따라 계속 진행할지, 취소할지, 전환할지 정할 수 있습니다.

계속 진행한다는 가정 하에, 데이터 조각을 받을 때마다 콜백을 받으면 응답 진행률을 계산할 수도 있겠죠?

그리고 마지막에 한번만 호출되는 메서드에서는 콜백 클로저처럼 최종 응답 결과(데이터)를 한번에 확인할 수 있습니다.

URLSessionDataTask
"A data task returns data directly to the app (in memory) as one or more NSData objects."
 

URLSessionDataTask | Apple Developer Documentation

A URL session task that returns downloaded data directly to the app in memory.

developer.apple.com

 

저수준 내부 동작 방식까지는 공식문서에 명시하진 않았지만, 데이터 패킷을 받을 때마다 콜백을 받을 수 있는 것과 하나의 완성된 데이터를 마지막에 전달받는 것으로 보아 위 내부 동작을 충분히 뒷받침 할 수 있다고 생각합니다!

 

사실 흔히 앱 서비스를 사용할 때 어떤 네트워크 요청을 보내면 진행률을 시각적으로 표현해주는 UI를 볼 수 있는데, 막연하게 uploadTask나 downloadTask를 통해 진행률을 알 수 있겠거니 생각했습니다. 네트워크 요청 구현에 대한 지식이 다소 얕았던 탓이죠..ㅎ 반성합니다..

반응형