URLSession — 是什么,网络 API 以及在 iOS 中如何工作

作者: IT Sectr 发布日期: 2026-03-07 阅读时间: 8 分钟

URLSession — 是 iOS 和 macOS 中用于网络请求的 API,属于 Foundation 框架的一部分,提供统一的接口来处理 HTTP、HTTPS、后台下载和 WebSocket。它取代了已过时的 NSURLConnection,并成为 Apple 开发者的主要网络工具。根据 Apple Developer Documentation (2025)URLSession 处理超过 90% 的 iPhone 和 iPad 应用中的网络流量。

要点

  • URLSession — Apple 原生的网络请求、HTTP、文件下载和 WebSocket API
  • 任务类型:dataTask(请求)、downloadTask(下载)、uploadTask(上传)、webSocketTask
  • 配置决定会话的行为:缓存、超时、代理、凭据
  • 异步性通过闭包、委托或现代的 async/await 实现
  • 后台会话允许在应用最小化时也能下载数据

什么是 URLSession?

URLSession — 是 Apple 在 iOS 7 和 macOS 10.9 中引入的网络操作 API。它取代了 NSURLConnection,提供了更灵活、更强大的网络工作模型。该库支持 HTTP/1.1、HTTP/2、HTTP/3 和 WebSocket,以及用于数据下载的后台会话。

URLSession 相对于旧的 NSURLConnection 的主要优势——通过单一会话支持多个同时连接、可自定义配置以及暂停和恢复下载的能力。会话将一组网络任务与通用设置组合在一起:缓存、Cookie 策略、超时、TLS 证书。

在 iOS 中,URLSession 与系统 DNS 缓存、电源管理和后台进程协同工作。当应用最小化时,系统可以通过后台会话继续下载数据,并在完成后通过完成处理程序通知应用。后台会话对于下载大文件、更新内容以及同步处理文档和媒体文件的应用中的数据特别有用。要使用后台会话,需要实现 URLSessionDelegate 并在创建会话时传递配置标识符——系统在应用重启后使用此标识符来恢复会话。

URLSession 的一个重要优势是支持 HTTP/2HTTP/3。HTTP/2 的多路复用允许通过单个 TCP 连接发送多个请求,从而减少延迟和服务器负载。基于 UDP 之上的 QUIC 协议的 HTTP/3,通过消除 TCP 握手实现更快速的连接建立。

URLSession 的架构

URLSession 的架构由三个关键组件组成:会话配置、会话本身和任务(tasks)。每个组件负责网络交互的一个方面,它们的组合决定了应用在网络工作时的行为。

URLSessionConfiguration

配置设置会话参数——从超时到缓存策略。有三种类型:.default(带磁盘缓存的标准配置)、.ephemeral(不保存缓存和 Cookie)和 .background(用于后台下载)。在配置中可以设置每个主机的最大连接数、请求和资源超时、TLS 策略和代理。

URLSessionTask 任务类型

URLSessionTask — 是所有网络操作的基类。主要子类:URLSessionDataTask 用于 GET 和 POST 请求,在内存中返回数据;URLSessionDownloadTask 用于下载文件到磁盘;URLSessionUploadTask 用于上传文件到服务器;URLSessionWebSocketTask 用于从 iOS 13 开始使用 WebSocket。

URLSession 委托

会话委托接收关于任务进度的事件:数据接收、下载完成、身份验证错误、重定向。URLSessionDelegate 及其子协议允许在身份验证时拦截 TLS 证书、通过 URLCache 管理响应缓存以及监控大文件下载进度。作为替代方案,在不需要处理中间事件的简单情况下,可以使用闭包(完成处理程序)。

如何使用 URLSession 发起请求

使用 URLSession 的基本场景如下:创建配置,基于配置创建会话,然后通过会话创建带有 URL 请求的任务,并启动任务。让我们分析一个带有闭包的 GET 请求示例。此模式在大多数 iOS 应用中用于从 REST API 获取数据、加载图像以及与云服务交互。

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!.localizedDescription)")
        return
    }
    if let json = try? JSONSerialization.jsonObject(with: data) {
        print("JSON: \(json)")
    }
}
task.resume()

在示例中使用 URLSession.shared — 一个带有 .default 配置的单例,用于简单请求。dataTask 创建一个异步操作,但不会启动它——必须调用 resume()。闭包在请求完成后执行,并返回 data、response 或 error。对于具有自定义配置的会话,使用 URLSession(configuration:) 初始化器,它允许为所有会话任务设置缓存策略、超时、最大连接数、默认 HTTP 标头和代理设置。这种方法可以完全控制应用中的网络行为。

通过 URLSession 下载文件

URLSession 支持具有暂停和恢复功能的文件下载,以及后台下载。DownloadTask 将文件保存到临时目录,在完成闭包中需要将其移动到永久位置。

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

闭包中的 location 参数指向需要移动的临时文件,否则系统将在退出闭包后将其删除。为了跟踪进度,使用 URLSessionDownloadDelegate 委托及其 didWriteData 方法,该方法传递已写入的字节数和文件总大小——这些数据可用于在用户界面中显示进度条。带有 downloadTask 的后台会话允许在应用最小化后继续下载,完成后系统调用 AppDelegate 中的处理程序。

URLSession 与 Alamofire 对比

Alamofire — 是一个构建在 URLSession 之上的 Swift 库,提供更声明式的接口。原生 API 和 Alamofire 之间的选择取决于项目的复杂性和团队的偏好。

标准URLSessionAlamofire
依赖无,内置于 Foundation需要 SPM 或 CocoaPods
语法带闭包的命令式带链式调用的声明式
JSON 处理手动 JSONSerializationresponseDecodable 配合 Codable
拦截器通过委托RequestInterceptor, EventMonitor
进度通过委托downloadProgress, uploadProgress

对于简单项目,URLSession 已经足够且不增加依赖。Alamofire 适用于具有大量网络请求、复杂错误处理和需要简洁语法的项目。这两种技术都使用共同的 URLSessionConfiguration 基础,并且相互兼容。在选择时需要考虑,URLSession 完全由 Apple 控制并随 iOS 更新,而 Alamofire 需要库开发者支持与新 OS 版本的兼容性。

URLSession 代码示例

现代 Swift 支持 async/await,这使得网络请求比闭包更易读。让我们看看使用异步语法的同一个 GET 请求。

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
}

data(from:) 方法从 iOS 15 和 macOS 12 开始可用。它返回一个元组 (Data, URLResponse),并在网络问题时抛出错误。使用 Codable 模型的 JSONDecoder 自动反序列化响应——这取代了前面示例中繁琐的 JSONSerialization。

带 JSON 正文的 POST 请求

对于带 JSON 正文的 POST 请求,使用 URLRequest,在其中配置方法、Content-Type 标头和 Data 格式的请求正文。Async/await 使这个过程简洁明了,而错误处理通过 do-catch 块也很简单。

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

常见问题

URLSession 与 NSURLConnection 有什么区别?

URLSession 是 NSURLConnection 的现代替代品,在 iOS 7 中引入。主要区别:通过会话支持多个连接、暂停和恢复任务、后台下载和 WebSocket。NSURLConnection 已过时,不建议在新项目中使用。

如何在 URLSession 中跟踪下载进度?

要跟踪进度,使用 URLSessionDownloadDelegate 委托及其 urlSession(_:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite) 方法。对于 dataTask,可以订阅 URLSessionTaskDelegate 并通过 didSendBodyData 接收更新。

如何使用 URLSession 进行后台下载?

后台下载通过 .background(withIdentifier:) 配置进行设置。应用在 AppDelegate 中注册完成处理程序,并在最小化或关闭后仍能接收结果。系统管理下载并通过 sessionDidFinishEvents 委托通知应用。

URLSession 可以用于 WebSocket 吗?

是的,从 iOS 13 开始,URLSession 通过 URLSessionWebSocketTask 类支持 WebSocket。它通过 webSocketTask(with:) 方法创建,并提供 send、receive 方法,支持文本和二进制消息,以及用于保持连接的 ping/pong。

如何在 URLSession 中设置超时?

超时通过 URLSessionConfiguration 设置:timeoutIntervalForRequest(等待请求响应)和 timeoutIntervalForResource(整个下载的最长时间)。默认值:请求 60 秒,资源 7 天。

总结

  • URLSession — Apple 原生的网络请求 API,支持 HTTP、后台下载和 WebSocket
  • 三种配置类型(.default、.ephemeral、.background)决定会话行为
  • 四种任务类型涵盖所有场景:dataTask、downloadTask、uploadTask、webSocketTask
  • 委托允许管理身份验证、进度和重定向
  • Async/await 从 iOS 15 开始使 URLSession 代码更可读、更简洁
  • 选择 URLSession 或 Alamofire 取决于项目规模——URLSession 足以完成简单任务

我们将开发一款交钥匙移动应用程序

IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。

讨论项目

另请阅读