AVAssetDownloadTask method 'didFinishDownloadingTo' is not called in background mode with low disk space

894 Views Asked by At

I create a background session like this:

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)

Also create and run a task:

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

But if I have less than 500MB of disk space on my real device the application is restarted and the following method is called:

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

But the next method is not called:

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

The file is not deleted from the device, how can I find out where it is locally and how to delete it? The system does not do this automatically.

Checked many times on real iphone 6s, iOS 14.0.1 with logs and Mac OS console application.

If the memory is more than 500 MB, then everything works correctly and the method didCompleteWithError is called

1

There are 1 best solutions below

0
On

You can use AVAggregateAssetDownloadTask to get a location of your downloading media in URLSession:aggregateAssetDownloadTask:willDownloadToURL:e.g.:

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

How to work with aggregate tasks you can look at Apple's sample project: https://developer.apple.com/documentation/avfoundation/media_playback_and_selection/using_avfoundation_to_play_and_persist_http_live_streams