URLSession downloadTask cannot configure timeout and also cannot downlaod with resume data

Using URLSession downloadTask to download some file from URL, by setting timeoutIntervalForResource of the session configuration, and in urlSession(_:task:didCompleteWithError:) delegate trying to get resumeData with NSURLSessionDownloadTaskResumeData key then using downloadTask(withResumeData:) to download with resume data.

The same code works on macOS as expected but does not work on Linux environment.

Code demo:

import Foundation
#if canImport(FoundationNetworking)
import FoundationNetworking
#endif

final class DownloadTool: NSObject {

    private lazy var session: URLSession = {
        let configuration = URLSessionConfiguration.default
        configuration.timeoutIntervalForResource = 5
        return URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
    }()

    private var progress = 0

    func start(_ url: URL) {
        session.downloadTask(with: url).resume()
    }
}

extension DownloadTool: URLSessionDownloadDelegate {

    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
        print("Download succeeded")
    }

    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        guard let error = error else { return }
        print(error)

        guard let resumeData = (error as NSError).userInfo[NSURLSessionDownloadTaskResumeData] as? Data else {
            print("Download failed")
            return
        }
        session.downloadTask(withResumeData: resumeData).resume()
    }

    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
        let currProgress = Int(Double(totalBytesWritten) / Double(totalBytesExpectedToWrite) * 100)
        if progress == currProgress { return }
        progress = currProgress
        print("Downloading in progress: \(progress)%")
    }
}

The same code works on macOS as expected but does not work on Linux environment.

This could be because of the presence of nsurlsessiond on macOS or that because downloadTaskResumeData is not available on Linux. However someone from the core team would need to confirm this though.

1 Like