【问题标题】:How to get reference of a background file-download Task in Swift?如何在 Swift 中获取后台文件下载任务的参考?
【发布时间】:2018-07-22 16:11:53
【问题描述】:

我可以在后台成功下载文件。 关闭应用并重新打开应用后,仍会按预期下载数据。

但是,为了根据数据下载状态显示 UI,我需要参考实际的后台任务。我特别想知道是否还有一个后台任务正在运行 - 如果是,我需要对这个特定任务的引用。

我该怎么做??

根据我的阅读,这个引用应该由首先配置为后台会话的 downloadSession 自动提供(即self.downloadService.downloadsSession = self.downloadsSession)。但这并没有以某种方式做到这一点......

此外,我通过 a) 按下模拟器中的停止按钮或 b) 通过双击 Home 并将应用程序滑出多线程视图来杀死我的应用程序 --> 这对保持后台任务有效吗?为下一个应用程序启动?? (至少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)
}

【问题讨论】:

    标签: swift background urlsession nsurlsessionconfiguration


    【解决方案1】:

    当您使用downloadTask(with:) 创建任务时,会返回一个URLSessionDownloadTask。只要您的程序仍在运行,您就可以使用该任务访问下载信息。我相信您的问题是当您的程序终止并重新启动时如何处理。

    每个任务都有一个taskIdentifier。您可以创建一个字典,将标识符映射到对您的内部跟踪有用的任何内容(URL、常量等)。重新启动时,您可以调用 URLSession.shared.getTasksWithCompletionHandler() 来检索所有正在进行的任务,并使用标识符映射回您用来跟踪它们的任何内容。

    如果您只关心 URL,则可以跳过整个标识符步骤,只需使用 originalRequest 来确定您关心的是哪个。

    【讨论】:

    • 非常感谢 Rob 的详细回答。我试试看!
    • 它可以工作——除了:如果我离开启动 DownloadTask 的 VC 并重新输入它(通过segue to Detail-VC 或通过属性的持久性和storyboard!.instantiateVC):重新输入VC 不再更新 UI(例如 progressBar 或 progressLabel !(在委托方法(例如 urlSession(...didWriteData bytesWritten...)urlsSession(...didFinischDownloadingTo location...))中,重新输入很好地 [通过您描述的方法] - 但再次:没有 UIProgressView- 或如果在提到的两个委托方法之一中发生更改,UILabel 将更新 UI!
    • 请同时参考我打开的这个问题,因为这个问题让我从 2 天开始就抓狂了!! LINK
    • @iKK 视图控制器不应管理下载任务(或任何网络行为)。他们只对屏幕上的视图负责。网络操作独立发生。您需要将网络操作移至与屏幕上发生的内容无关的较低级别的对象。
    • 现在可以使用了!!!!!! : 哦,Rob,你帮了大忙! :) 我不知道这个下载任务的.progress 附件可能性。我学得很快:)。非常感谢您在这里的帮助!
    猜你喜欢
    • 2011-10-05
    • 2012-01-06
    • 2015-10-14
    • 1970-01-01
    • 1970-01-01
    • 2019-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多