使用 Swift 并发 URLSession API 下载文件
了解如何使用 iOS 15 引入的全新基于并发的 URLSession 方法,在 SwiftUI 应用中获取和存储远程数据。

在 iOS 15 及之后的系统中,URLSession
扩展了 Swift Concurrency 功能,新增了一系列 async/await
风格的网络请求方法,用简单优雅的 async/await
语法取代了繁琐的回调模式,使代码更加可读和易于维护。
新的 API 包括:
data(for:delegate:)
download(for:delegate:)
upload(for:from:delegate:)
新的 API 简介
data(for:delegate:)
发起一般的网络请求,拿回响应的 Data
和 URLResponse
。常用于请求 JSON、XML、或其他格式的文本、二进制数据,拿到后做进一步解析。
适用场合
- 适合小或中等体量的数据传输:比如 JSON 响应、图片、文本、二进制文件等。
- 需要一次性将所有数据加载到内存 的场景:例如解析 JSON 或用
UIImage(data:)
直接创建图片。
download(for:delegate:)
下载大文件、视频、音频等,将其直接存储到临时文件而非内存中。
适用场合
- 下载大文件:因为它无需把整个文件都加载进内存,而是直接写到临时文件。
- 视频/音频/压缩包 等较大体量资源。
- 想要在后台下载 或希望可以进行断点续传(
URLSessionDownloadDelegate
)。
upload(for:from:delegate:)
实现大文件或表单数据的上传,并将其转换成并发友好的 async/await
流程。和 data(for:)
类似,但侧重点是把本地文件或数据上传到服务器。
适用场合
- 上传表单、图像、视频 等需要较大带宽的上传任务。
- 后台上传:同样可以通过设置自定义的
URLSession(configuration:delegate:delegateQueue:)
来支持后台上传和进度监听。
URLSession.shared.download(for:delegate:)
这个 API 的核心是 download(for:)
方法,它返回一个元组 (URL, URLResponse)
。元组的,
- 第一个元素表示下载数据的本地文件位置
- 第二个元素是 URL 响应
处理下载
以下是在异步上下文中构建下载函数的示例:
func downloadFile(from url: URL) async throws -> URL {
// 1. 从 URL 创建请求
let request = URLRequest(url: url)
// 2. 使用 Swift 并发执行下载
let (fileURL, response) = try await URLSession.shared.download(for: request)
// 3. (可选)如果需要,验证响应
guard let httpResponse = response as? HTTPURLResponse,
httpResponse.statusCode == 200 else {
throw URLError(.badServerResponse)
}
// 4. 返回临时文件 URL(您可以将其移动到永久位置)
return fileURL
}
方法参数
- URLRequest: 定义要下载的远程资源的请求。
- URL: 下载资源的临时文件 URL。
- URLResponse: 包含响应的元数据,例如状态码和头信息。
需要将文件从临时位置移动或复制到更持久的目录。
显示下载进度
该方法目前未提供直接获取下载进度信息的能力。