在磁盘空间不足的后台模式下未调用AVAssetDownloadTask方法'didFinishDownloadingTo'

问题描述

我创建这样的后台会话:

let backgroundConfiguration = URLSessionConfiguration.background(withIdentifier: backgroundSessionId)
backgroundConfiguration.isdiscretionary = false
backgroundConfiguration.sessionSendsLaunchEvents = true backgroundConfiguration.shouldUseExtendedBackgroundIdleMode = true
privateQueue = OperationQueue()
privateQueue.maxConcurrentOperationCount = 1
assetDownloadSession = AVAssetDownloadURLSession(configuration: backgroundConfiguration,assetDownloadDelegate: self,delegateQueue: privateQueue)

还创建并运行任务:

let task = assetDownloadSession.makeAssetDownloadTask(asset: urlAsset,assetTitle: title,assetArtworkData: nil,options: nil)
task.resume()

但是,如果我的真实设备上的磁盘空间不足500MB,则会重新启动应用程序,并调用以下方法

func urlSession(_ session: URLSession,task: URLSessionTask,didCompleteWithError error: Error?)

但是不调用一个方法

func urlSession(_ session: URLSession,assetDownloadTask: avassetdownloadtask,didFinishDownloadingTo location: URL)

文件未从设备中删除,如何找到它在本地的位置以及如何删除它?系统不会自动执行此操作。

在真实的iPhone 6s,带有日志的iOS 14.0.1和Mac OS控制台应用程序上进行了多次检查。

如果内存超过500 MB,则一切正常,并调用方法didCompleteWithError

解决方法

您可以使用AVAggregateAssetDownloadTaskURLSession:aggregateAssetDownloadTask:willDownloadToURL:中获取下载媒体的位置,例如:

var assetDownloadURLSession: AVAssetDownloadURLSession!
var task = AVAggregateAssetDownloadTask?
var downloadURL: URL?

func download(asset: AVURLAsset)
    let backgroundConfiguration = URLSessionConfiguration.background(withIdentifier: "AAPL-Identifier")
    assetDownloadURLSession = AVAssetDownloadURLSession(configuration: backgroundConfiguration,assetDownloadDelegate: self,delegateQueue: OperationQueue.main)
    task = assetDownloadURLSession.aggregateAssetDownloadTask(with: asset,...)
    task?.resume()
    ...
}

func urlSession(_ session: URLSession,aggregateAssetDownloadTask: AVAggregateAssetDownloadTask,willDownloadTo location: URL) {
    downloadURL = location
}

func urlSession(_ session: URLSession,task: URLSessionTask,didCompleteWithError error: Error?) {
    if let url = downloadURL {
        do {
            try FileManager.default.removeItem(at: url)
        }
        catch {
            print(error)
        }
    }
}

如何处理聚合任务,您可以查看Apple的示例项目:https://developer.apple.com/documentation/avfoundation/media_playback_and_selection/using_avfoundation_to_play_and_persist_http_live_streams