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

如何在下次启动时恢复AVAggregateAssetDownloadTask下载任务?

解决AVAggregateAssetDownloadTask重启APP后恢复下载的方案

我来帮你搞定这个问题~虽然旧的指定目标文件夹的API被废弃了,但结合URLSession的后台恢复机制+本地元数据持久化,完全可以实现重启后恢复下载的需求,具体步骤如下:

一、核心思路

现在的AVAggregateAssetDownloadTask基于AVAssetDownloadURLSession(继承自URLSession),所以我们要利用URLSession的后台任务恢复能力,再配合本地保存的下载元数据,就能在APP重启后找回未完成的任务,或者重新构建任务继续下载。

二、具体实现步骤

1. 下载前持久化关键元数据

在启动下载前,把恢复任务必需的信息保存到本地(比如UserDefaults或CoreData),至少要包含:

  • 待下载资源的AVURLAsset的URL
  • 下载时指定的AVMediaSelection(如果有音轨/字幕选择的话)
  • 自定义的业务标识(比如视频ID,方便关联业务逻辑)

示例代码:

// 假设你已经创建了AVURLAsset和对应的mediaSelection
let assetURL = URL(string: "你的流媒体地址")!
let mediaSelection = asset.preferredMediaSelection

// 把信息转成可持久化的格式
let downloadMetaData = [
    "assetURL": assetURL.absoluteString,
    "mediaSelectionData": mediaSelection.dataRepresentation(),
    "videoID": "自定义业务ID"
] as [String: Any]

// 保存到UserDefaults
UserDefaults.standard.set(downloadMetaData, forKey: "PendingAssetDownload")

2. 启动APP时恢复任务

APP启动后,先通过固定标识的后台URLSession创建实例,系统会自动帮我们找回未完成的任务;如果系统没恢复成功,再用本地保存的元数据重新构建任务。

示例代码:

// 注意:这里的session identifier必须固定,系统靠它识别后台任务
let config = URLSessionConfiguration.background(withIdentifier: "com.your.app.assetDownloadSession")
let downloadSession = AVAssetDownloadURLSession(configuration: config, 
                                               assetDownloadDelegate: self, 
                                               delegateQueue: OperationQueue.main)

// 第一步:获取系统已恢复的任务
downloadSession.getAllTasks { tasks in
    for task in tasks {
        if let aggregateTask = task as? AVAggregateAssetDownloadTask {
            // 关联你的业务逻辑,比如更新UI显示下载进度
            self.continueExistingTask(aggregateTask)
        }
    }
}

// 第二步:如果没有找到可恢复的任务,用本地元数据重新创建
if let metaData = UserDefaults.standard.dictionary(forKey: "PendingAssetDownload"),
   let assetURLStr = metaData["assetURL"] as? String,
   let assetURL = URL(string: assetURLStr),
   let mediaData = metaData["mediaSelectionData"] as? Data {
    
    let asset = AVURLAsset(url: assetURL)
    guard let mediaSelection = try? AVMediaSelection(dataRepresentation: mediaData, for: asset) else {
        return
    }
    
    // 创建新的聚合下载任务并启动
    let newTask = downloadSession.aggregateAssetDownloadTask(with: asset, 
                                                             mediaSelections: [mediaSelection], 
                                                             assetDownloadOptions: nil)
    newTask?.resume()
}

3. 处理代理方法,维护任务状态

在AVAssetDownloadDelegate的回调里,更新下载进度、处理完成/错误情况,同时及时更新本地持久化的信息:

// 单个媒体轨道下载完成
func urlSession(_ session: URLSession, aggregateAssetDownloadTask: AVAggregateAssetDownloadTask, didCompleteFor mediaSelection: AVMediaSelection) {
    // 可以在这里更新单个轨道的完成状态
}

// 下载进度更新
func urlSession(_ session: URLSession, aggregateAssetDownloadTask: AVAggregateAssetDownloadTask, didLoad timeRange: CMTimeRange, totalTimeRangesLoaded loadedTimeRanges: [NSValue], timeRangeExpectedToLoad: CMTimeRange) {
    // 计算进度并更新UI
    let totalLoaded = loadedTimeRanges.reduce(CMTime.zero) { $0 + $1.timeRangeValue.duration }
    let progress = CMTimeGetSeconds(totalLoaded) / CMTimeGetSeconds(timeRangeExpectedToLoad.duration)
    print("当前下载进度:\(progress)")
}

// 任务完成/出错
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
    if let error = error {
        let nsError = error as NSError
        // 如果是用户主动取消,清除本地持久化数据
        if nsError.code == NSURLErrorCancelled {
            UserDefaults.standard.removeObject(forKey: "PendingAssetDownload")
        }
        // 其他错误(比如网络中断),保留本地数据,下次启动继续
    } else {
        // 下载完全完成,清除本地持久化数据
        UserDefaults.standard.removeObject(forKey: "PendingAssetDownload")
    }
}

三、关键注意事项

  • 必须使用后台URLSession配置(background(withIdentifier:)),并且identifier要固定,这是系统恢复后台任务的核心依据。
  • 不要手动指定下载目标路径,现在的API由系统统一管理离线内容的存储位置,你可以通过aggregateAssetDownloadTask.urlAsset直接访问已下载的离线资源。
  • 持久化的元数据要足够完整,尤其是AVMediaSelection,因为AVAggregateAssetDownloadTask是针对特定媒体选择(比如音轨、字幕)创建的,缺失的话无法正确恢复任务。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:06:16