You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在应用终止后恢复URLSessionDownloadTask下载任务?

重启应用后恢复URLSessionDownloadTask下载进度的实现方案

完全可以通过URLSessionDownloadTask实现,不需要额外依赖第三方库。核心是利用resumeData持久化和固定标识符的后台会话,步骤如下:

1. 暂停下载时保存恢复数据

当用户主动暂停下载,或者应用即将退出前,调用下载任务的cancel(byProducingResumeData:)方法生成恢复数据,将其持久化到本地(比如UserDefaults或文件,大文件推荐文件存储):

// 主动暂停下载时执行
self.task?.cancel { [weak self] resumeData in
    guard let resumeData = resumeData else { return }
    // 保存resumeData到UserDefaults
    UserDefaults.standard.set(resumeData, forKey: "DownloadResumeDataKey")
}

2. 重启应用后恢复下载

应用启动时,优先读取本地保存的resumeData,用同一个后台会话标识符创建恢复任务;如果没有有效resumeData,再创建新下载任务:

self.fileDownloadUrl = "www.example.com"
let sessionIdentifier = "com.example.app"

// 尝试读取保存的恢复数据
if let resumeData = UserDefaults.standard.data(forKey: "DownloadResumeDataKey") {
    let config = URLSessionConfiguration.background(withIdentifier: sessionIdentifier)
    self.session = URLSession(configuration: config, delegate: self, delegateQueue: nil)
    // 通过resumeData恢复下载任务
    self.task = self.session!.downloadTask(withResumeData: resumeData)
    self.task?.resume()
} else if let downloadUrlStr = self.fileDownloadUrl, let fileUrl = URL(string: downloadUrlStr) {
    // 无恢复数据,创建新任务
    let config = URLSessionConfiguration.background(withIdentifier: sessionIdentifier)
    self.session = URLSession(configuration: config, delegate: self, delegateQueue: nil)
    let request = URLRequest(url: fileUrl)
    self.task = self.session!.downloadTask(with: request)
    self.task?.resume()
} else {
    self.unownedErrorPopUp.showAnimation()
}

关键注意事项

  • 后台会话的identifier必须固定,确保系统能关联会话状态。
  • 处理resumeData失效:如果恢复下载失败(比如服务器资源变更),在URLSessionDelegate的urlSession(_:task:didFailWithError:)方法中捕获.resumeDataInvalid错误,删除本地保存的resumeData后重新发起下载。
  • 下载完成后,记得清除本地保存的resumeData,避免下次启动误触发恢复流程。

内容的提问来源于stack exchange,提问作者KimJitae

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 10:18:27