URLSession — What It Is, Network API, and How It Works in iOS

Author: IT Sectr Published: 2026-03-07 Reading time: 8 min

URLSession is an API for network requests in iOS and macOS, part of the Foundation framework that provides a unified interface for working with HTTP, HTTPS, background downloads, and WebSocket. It replaced the outdated NSURLConnection and became the primary networking tool for Apple developers. According to Apple Developer Documentation (2025), URLSession handles over 90% of network traffic in iPhone and iPad applications.

Key Takeaways

  • URLSession — Apple’s native API for network requests, HTTP, file downloads, and WebSocket
  • Task types: dataTask (requests), downloadTask (downloading), uploadTask (uploading), webSocketTask
  • Session configuration determines behavior: caching, timeouts, proxies, credentials
  • Asynchronicity is implemented through closures, delegates, or modern async/await
  • Background sessions allow data loading even when the app is minimized

What is URLSession?

URLSession is an API for network operations introduced by Apple in iOS 7 and macOS 10.9. It replaced NSURLConnection and provided a more flexible and powerful model for working with the network. The library supports HTTP/1.1, HTTP/2, HTTP/3, and WebSocket, as well as background sessions for data loading.

The main advantage of URLSession over the old NSURLConnection is support for multiple simultaneous connections through a single session, configurable configurations, and the ability to pause and resume downloads. A session combines a group of network tasks with shared settings: caching, cookie policy, timeouts, TLS certificates.

In iOS, URLSession works with the system DNS cache, power management, and background processes. When the app is minimized, the system can continue loading data through a background session, and upon completion, notify the app via a completion handler. Background sessions are especially useful for downloading large files, updating content, and synchronizing data in document and media applications. To work with background sessions, you need to implement the URLSessionDelegate and pass a configuration identifier when creating the session — the system uses this identifier to restore the session after an app restart.

An important advantage of URLSession is support for HTTP/2 and HTTP/3. HTTP/2 multiplexing allows sending multiple requests over a single TCP connection, reducing latency and server load. HTTP/3, based on the QUIC protocol over UDP, provides even faster connection establishment by eliminating the TCP handshake.

URLSession Architecture

The URLSession architecture consists of three key components: session configuration, the session itself, and tasks. Each component is responsible for its own aspect of network interaction, and their combination determines the application’s behavior when working with the network.

URLSessionConfiguration

Configuration sets session parameters — from timeouts to caching policies. There are three types: .default (standard with disk cache), .ephemeral (without saving cache and cookies), and .background (for background downloads). In the configuration, you can specify the maximum number of connections per host, request and resource timeout, TLS policy, and proxy settings.

URLSessionTask Types

URLSessionTask is the base class for all network operations. The main subclasses are: URLSessionDataTask for GET and POST requests returning data in memory, URLSessionDownloadTask for downloading files to disk, URLSessionUploadTask for uploading files to the server, and URLSessionWebSocketTask for working with WebSocket since iOS 13.

URLSession Delegates

The session delegate receives events about task progress: data reception, download completion, authentication errors, redirects. URLSessionDelegate and its sub-protocols allow intercepting TLS certificates during authentication, managing response caching through URLCache, and monitoring download progress for large files. Alternatively, closures (completion handlers) can be used for simple cases where intermediate event handling is not required.

How to Make Requests with URLSession

The basic workflow with URLSession looks like this: create a configuration, create a session based on it, then create a task with a URL request through the session, and start the task. Let’s walk through an example GET request with a closure. This pattern is used in most iOS applications for fetching data from REST APIs, loading images, and interacting with cloud services.

swift
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()

The example uses URLSession.shared — a singleton with .default configuration for simple requests. dataTask creates an asynchronous operation but does not start it — you must call resume(). The closure fires after the request completes and returns data, response, or error. For a custom session with your own configuration, use the URLSession(configuration:) initializer, which allows setting caching policies, timeouts, maximum connections, default HTTP headers, and proxy settings for all session tasks. This approach gives you full control over network behavior in your application.

Downloading Files via URLSession

URLSession supports file downloads with the ability to pause and resume, as well as background downloads. DownloadTask saves the file to a temporary directory, and in the completion closure, you need to move it to a permanent location.

swift
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()

The location parameter in the closure points to a temporary file that needs to be moved, otherwise the system will delete it after the closure exits. To track progress, use the URLSessionDownloadDelegate with the didWriteData method, which passes the number of bytes written and the total file size — this data can be used to display a progress bar in the user interface. Background sessions with downloadTask allow you to continue downloading even after the app is minimized, and upon completion, the system calls the handler in AppDelegate.

URLSession vs Alamofire

Alamofire is a Swift library built on top of URLSession that provides a more declarative interface. The choice between the native API and Alamofire depends on the project’s complexity and team preferences.

CriterionURLSessionAlamofire
DependenciesNone, built into FoundationRequires SPM or CocoaPods
SyntaxImperative with closuresDeclarative with chaining
JSON HandlingManual JSONSerializationresponseDecodable with Codable
InterceptorsThrough delegatesRequestInterceptor, EventMonitor
ProgressThrough delegatedownloadProgress, uploadProgress

For simple projects, URLSession is sufficient and adds no dependencies. Alamofire is justified in projects with many network requests, complex error handling, and a need for concise syntax. Both technologies share the common URLSessionConfiguration foundation and are compatible with each other. When choosing, consider that URLSession is fully controlled by Apple and updates with iOS, while Alamofire requires the library developers to maintain compatibility with new OS versions.

URLSession Code Examples

Modern Swift supports async/await, which makes network requests more readable compared to closures. Let’s look at the same GET request using asynchronous syntax.

swift
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
}

The data(from:) method is available since iOS 15 and macOS 12. It returns a tuple (Data, URLResponse) and throws an error on network issues. JSONDecoder with a Codable model automatically deserializes the response — this replaces the cumbersome JSONSerialization from the previous example.

POST Request with JSON Body

For POST requests with a JSON body, URLRequest is used, where you configure the method, Content-Type headers, and the request body as Data. Async/await makes this process concise and clear, and error handling is simple through a do-catch block.

swift
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)
}

Frequently Asked Questions

How is URLSession different from NSURLConnection?

URLSession is the modern replacement for NSURLConnection, introduced in iOS 7. The main differences include support for multiple connections through sessions, task suspension and resumption, background downloads, and WebSocket. NSURLConnection is deprecated and not recommended for use in new projects.

How to track download progress in URLSession?

To track progress, use the URLSessionDownloadDelegate with the urlSession(_:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite) method. Alternatively, for dataTask, you can subscribe to URLSessionTaskDelegate and receive updates via didSendBodyData.

How to perform background downloads with URLSession?

Background downloads are configured through the .background(withIdentifier:) configuration. The app registers a completion handler in AppDelegate and receives results even after being minimized or closed. The system manages the download and notifies the app through the sessionDidFinishEvents delegate.

Can URLSession be used with WebSocket?

Yes, since iOS 13, URLSession supports WebSocket through the URLSessionWebSocketTask class. It is created with the webSocketTask(with:) method and provides send, receive methods with support for text and binary messages, as well as ping/pong for keeping the connection alive.

How to set up timeouts in URLSession?

Timeouts are configured through URLSessionConfiguration: the timeoutIntervalForRequest property (waiting for a response to a request) and timeoutIntervalForResource (maximum time for the entire download). Defaults: 60 seconds for request and 7 days for resource.

Summary

  • URLSession — Apple’s native API for network requests, supporting HTTP, background downloads, and WebSocket
  • Three configuration types (.default, .ephemeral, .background) determine session behavior
  • Four task types cover all scenarios: dataTask, downloadTask, uploadTask, webSocketTask
  • Delegates allow managing authentication, progress, and redirects
  • Async/await since iOS 15 makes URLSession code more readable and concise
  • Choosing URLSession or Alamofire depends on project size — URLSession is sufficient for simple tasks

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also