我可以在后台成功下载文件。
关闭应用程序并重新打开应用程序时,仍有数据按预期下载。
但是,为了根据数据下载状态显示ui,需要参考实际的后台任务。我特别想知道是否还有一个后台任务在运行-如果是,我需要这个特定任务的引用。
我该怎么做?是吗?
从我所读到的内容来看,这个引用应该首先由配置为后台会话(即self.downloadService.downloadsSession = self.downloadsSession)的下载会话自动给出。但这并不能解决问题…
此外,我通过a)按模拟器中的“停止”按钮或b)双击“主页”并将应用从多线程视图中划出-->来终止我的应用程序这对于在下次应用程序启动时保持后台任务活动有效吗??(至少didWriteData方法在a)或b)两个关闭的情况下继续触发)-因此我认为这是可以的)
这是我的代码(除了一个更大的项目-但你应该得到的想法)……

let downloadService = SomeDownloadService()

lazy var downloadsSession: URLSession = {
    let configuration = URLSessionConfiguration.background(withIdentifier: "SomeID.BGSessionConfiguration")
    return URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
}()

override func viewDidLoad() {
    super.viewDidLoad()

    self.downloadService.downloadsSession = self.downloadsSession

    // ...file is created somewhere else...
    self.downloadService.startDownload(file)
    // *** Until here everything OK - file starts downloading in the background *******

    // *** HOW DO I GET A REFERENCE TO THE BACKGROUND TASK RUNNING ???????
    // ????

    // *** KEEPS PRINTING 0 *** WHY ?????????????????????????
    print(self.downloadService.activeDownloads.count
}

// Updates progress info
// *** WORKS WELL - upon second App-Start there is still data coming in *******
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask,
                didWriteData bytesWritten: Int64, totalBytesWritten: Int64,
                totalBytesExpectedToWrite: Int64) {

    guard let url = downloadTask.originalRequest?.url,
        let download = self.downloadService.activeDownloads[url]  else {
            return
    }

    download.progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)

    let totalSize = ByteCountFormatter.string(fromByteCount: totalBytesExpectedToWrite, countStyle: .file)
}

最佳答案

使用downloadTask(with:)创建任务时,返回一个URLSessionDownloadTask。只要程序仍在运行,就可以使用该任务访问下载信息。我相信你的问题是当你的程序终止并重新启动时如何处理这个问题。
每个任务都有一个taskIdentifier。您可以创建一个字典,将标识符映射到对您的内部跟踪有用的任何内容(url、常量或任何内容)。重新启动时,可以调用URLSession.shared.getTasksWithCompletionHandler()来检索所有正在进行的任务,并使用标识符映射回用于跟踪它们的任何内容。
如果您只关心url,那么您可以跳过整个标识符步骤,只需使用originalRequest来确定您关心哪个。

10-08 08:23