URLSession은 iOS 및 macOS에서 네트워크 요청을 위한 API로, Foundation 프레임워크의 일부로서 HTTP, HTTPS, 백그라운드 다운로드 및 WebSocket 작업을 위한 통합 인터페이스를 제공합니다. 이는 구형 NSURLConnection을 대체하고 Apple 개발자를 위한 주요 네트워킹 도구가 되었습니다. Apple Developer Documentation (2025)에 따르면, URLSession은 iPhone 및 iPad 애플리케이션의 네트워크 트래픽 중 90% 이상을 처리합니다.
핵심 포인트
URLSession은 Apple이 iOS 7 및 macOS 10.9에서 도입한 네트워크 작업용 API입니다. 이는 NSURLConnection을 대체하고 네트워크 작업을 위한 더 유연하고 강력한 모델을 제공했습니다. 라이브러리는 HTTP/1.1, HTTP/2, HTTP/3 및 WebSocket뿐만 아니라 데이터 로딩을 위한 백그라운드 세션도 지원합니다.
기존 NSURLConnection에 비해 URLSession의 주요 장점은 단일 세션을 통한 여러 동시 연결 지원, 사용자 정의 가능한 구성, 다운로드 일시 중지 및 재개 기능입니다. 세션은 공유 설정(캐싱, 쿠키 정책, 타임아웃, TLS 인증서)을 가진 네트워크 작업 그룹을 통합합니다.
iOS에서 URLSession은 시스템 DNS 캐시, 전원 관리 및 백그라운드 프로세스와 함께 작동합니다. 앱이 최소화되면 시스템은 백그라운드 세션을 통해 데이터 로딩을 계속할 수 있으며, 완료 시 완료 핸들러를 통해 앱에 알릴 수 있습니다. 백그라운드 세션은 대용량 파일 다운로드, 콘텐츠 업데이트, 문서 및 미디어 애플리케이션의 데이터 동기화에 특히 유용합니다. 백그라운드 세션을 사용하려면 URLSessionDelegate를 구현하고 세션 생성 시 구성 식별자를 전달해야 합니다. 시스템은 이 식별자를 사용하여 앱 재시작 후 세션을 복원합니다.
URLSession의 중요한 장점은 HTTP/2 및 HTTP/3 지원입니다. HTTP/2 멀티플렉싱은 단일 TCP 연결을 통해 여러 요청을 전송할 수 있어 지연 시간과 서버 부하를 줄입니다. UDP 위의 QUIC 프로토콜을 기반으로 하는 HTTP/3는 TCP 핸드셰이크를 제거하여 더 빠른 연결 설정을 제공합니다.
URLSession 아키텍처는 세 가지 주요 구성 요소로 이루어져 있습니다: 세션 구성, 세션 자체, 그리고 작업입니다. 각 구성 요소는 네트워크 상호작용의 고유한 측면을 담당하며, 이들의 조합이 네트워크 작업 시 애플리케이션의 동작을 결정합니다.
구성은 타임아웃부터 캐싱 정책까지 세션 매개변수를 설정합니다. 세 가지 유형이 있습니다: .default(디스크 캐시가 있는 표준), .ephemeral(캐시 및 쿠키를 저장하지 않음), .background(백그라운드 다운로드용). 구성에서는 호스트당 최대 연결 수, 요청 및 리소스 타임아웃, TLS 정책, 프록시 설정을 지정할 수 있습니다.
URLSessionTask는 모든 네트워크 작업의 기본 클래스입니다. 주요 하위 클래스는 다음과 같습니다: 메모리에 데이터를 반환하는 GET 및 POST 요청용 URLSessionDataTask, 디스크에 파일을 다운로드하는 URLSessionDownloadTask, 서버에 파일을 업로드하는 URLSessionUploadTask, iOS 13부터 WebSocket을 처리하는 URLSessionWebSocketTask.
세션 델리게이트는 작업 진행에 대한 이벤트(데이터 수신, 다운로드 완료, 인증 오류, 리디렉션)를 수신합니다. URLSessionDelegate와 그 하위 프로토콜을 통해 인증 중 TLS 인증서 가로채기, URLCache를 통한 응답 캐싱 관리, 대용량 파일의 다운로드 진행 상황 모니터링이 가능합니다. 대안으로 중간 이벤트 처리가 필요하지 않은 간단한 경우에는 클로저(완료 핸들러)를 사용할 수 있습니다.
URLSession의 기본 작업 흐름은 다음과 같습니다: 구성을 만들고, 이를 기반으로 세션을 만들고, 세션을 통해 URL 요청이 있는 작업을 만든 다음 작업을 시작합니다. 클로저를 사용한 GET 요청 예제를 살펴보겠습니다. 이 패턴은 대부분의 iOS 애플리케이션에서 REST API에서 데이터를 가져오거나, 이미지를 로드하거나, 클라우드 서비스와 상호작용하는 데 사용됩니다.
let url = URL(string: "https://api.example.com/users")!
let session = URLSession.shared
let task = session.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
print("Error: \(error!.localizedDescription)")
return
}
if let json = try? JSONSerialization.jsonObject(with: data) {
print("JSON: \(json)")
}
}
task.resume()
이 예제에서는 간단한 요청을 위해 .default 구성의 싱글톤인 URLSession.shared를 사용합니다. dataTask는 비동기 작업을 생성하지만 시작하지는 않습니다 — resume()을 호출해야 합니다. 클로저는 요청 완료 후 실행되며 data, response 또는 error를 반환합니다. 자체 구성으로 사용자 정의 세션을 사용하려면 URLSession(configuration:) 초기화자를 사용하여 모든 세션 작업에 대한 캐싱 정책, 타임아웃, 최대 연결 수, 기본 HTTP 헤더 및 프록시 설정을 지정할 수 있습니다. 이 접근 방식은 애플리케이션에서 네트워크 동작을 완전히 제어할 수 있게 해줍니다.
URLSession은 일시 중지 및 재개 기능이 있는 파일 다운로드와 백그라운드 다운로드를 지원합니다. DownloadTask는 파일을 임시 디렉토리에 저장하며, 완료 클로저에서 파일을 영구 위치로 이동해야 합니다.
let url = URL(string: "https://example.com/file.zip")!
let session = URLSession(configuration: .default)
let task = session.downloadTask(with: url) { location, _, _ in
guard let location = location else { return }
let destination = FileManager.default.temporaryDirectory
.appendingPathComponent("file.zip")
try? FileManager.default.moveItem(at: location, to: destination)
}
task.resume()
클로저의 location 매개변수는 이동이 필요한 임시 파일을 가리킵니다. 이동하지 않으면 시스템이 클로저 종료 후 파일을 삭제합니다. 진행 상황을 추적하려면 URLSessionDownloadDelegate를 didWriteData 메서드와 함께 사용합니다. 이 메서드는 기록된 바이트 수와 총 파일 크기를 전달하며, 이 데이터는 사용자 인터페이스에서 진행 표시줄을 표시하는 데 사용할 수 있습니다. downloadTask를 사용한 백그라운드 세션은 앱이 최소화된 후에도 다운로드를 계속할 수 있으며, 완료 시 시스템이 AppDelegate의 핸들러를 호출합니다.
Alamofire는 URLSession 위에 구축된 Swift 라이브러리로, 더 선언적인 인터페이스를 제공합니다. 네이티브 API와 Alamofire 사이의 선택은 프로젝트의 복잡성과 팀의 선호도에 따라 달라집니다.
| 기준 | URLSession | Alamofire |
|---|---|---|
| 종속성 | 없음, Foundation에 내장 | SPM 또는 CocoaPods 필요 |
| 구문 | 클로저를 사용한 명령형 | 체이닝을 사용한 선언형 |
| JSON 처리 | 수동 JSONSerialization | Codable을 사용한 responseDecodable |
| 인터셉터 | 델리게이트를 통해 | RequestInterceptor, EventMonitor |
| 진행 상황 | 델리게이트를 통해 | downloadProgress, uploadProgress |
간단한 프로젝트의 경우 URLSession으로 충분하며 종속성이 추가되지 않습니다. Alamofire는 네트워크 요청이 많고, 복잡한 오류 처리가 필요하며, 간결한 구문이 필요한 프로젝트에서 정당화됩니다. 두 기술 모두 공통 URLSessionConfiguration 기반을 공유하며 서로 호환됩니다. 선택 시 URLSession은 Apple이 완전히 제어하며 iOS와 함께 업데이트되는 반면, Alamofire는 라이브러리 개발자가 새 OS 버전과의 호환성을 유지해야 한다는 점을 고려하세요.
최신 Swift는 async/await를 지원하여 클로저에 비해 네트워크 요청을 더 읽기 쉽게 만듭니다. 비동기 구문을 사용한 동일한 GET 요청을 살펴보겠습니다.
func fetchUsers() async throws -> [User] {
let url = URL(string: "https://api.example.com/users")!
let (data, _) = try await URLSession.shared.data(from: url)
let users = try JSONDecoder().decode([User].self, from: data)
return users
}
data(from:) 메서드는 iOS 15 및 macOS 12부터 사용 가능합니다. 이는 튜플(Data, URLResponse)을 반환하고 네트워크 문제 시 오류를 throw합니다. Codable 모델과 함께 JSONDecoder는 응답을 자동으로 역직렬화하여 이전 예제의 번거로운 JSONSerialization을 대체합니다.
JSON 본문이 있는 POST 요청의 경우 URLRequest를 사용하여 메서드, Content-Type 헤더 및 Data로서의 요청 본문을 구성합니다. Async/await는 이 프로세스를 간결하고 명확하게 만들며, do-catch 블록을 통한 오류 처리가 간단합니다.
func createUser(name: String) async throws -> User {
var request = URLRequest(url: URL(string: "https://api.example.com/users")!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let body = try JSONEncoder().encode(["name": name])
request.httpBody = body
let (data, _) = try await URLSession.shared.data(for: request)
return try JSONDecoder().decode(User.self, from: data)
}
자주 묻는 질문
URLSession은 NSURLConnection의 최신 대체품으로, iOS 7에서 도입되었습니다. 주요 차이점으로는 세션을 통한 여러 연결 지원, 작업 일시 중지 및 재개, 백그라운드 다운로드, WebSocket이 포함됩니다. NSURLConnection은 더 이상 사용되지 않으며 새 프로젝트에서 사용을 권장하지 않습니다.
진행 상황을 추적하려면 URLSessionDownloadDelegate를 urlSession(_:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite) 메서드와 함께 사용하세요. 대안으로 dataTask의 경우 URLSessionTaskDelegate를 구독하고 didSendBodyData를 통해 업데이트를 받을 수 있습니다.
백그라운드 다운로드는 .background(withIdentifier:) 구성을 통해 설정됩니다. 앱은 AppDelegate에 완료 핸들러를 등록하고 최소화 또는 종료 후에도 결과를 받습니다. 시스템이 다운로드를 관리하고 sessionDidFinishEvents 델리게이트를 통해 앱에 알립니다.
예, iOS 13부터 URLSession은 URLSessionWebSocketTask 클래스를 통해 WebSocket을 지원합니다. 이는 webSocketTask(with:) 메서드로 생성되며 텍스트 및 바이너리 메시지를 지원하는 send, receive 메서드와 연결 유지를 위한 ping/pong을 제공합니다.
타임아웃은 URLSessionConfiguration을 통해 구성됩니다: timeoutIntervalForRequest 속성(요청에 대한 응답 대기) 및 timeoutIntervalForResource(전체 다운로드 최대 시간). 기본값: 요청 60초, 리소스 7일.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.