gpt4 book ai didi

swift - 我们可以在 swift 中分别使用多个 UIViewController 中的 URLSessionDelegate 方法同时下载文件吗

转载 作者:行者123 更新时间:2023-11-30 11:37:54 25 4
gpt4 key购买 nike

// Stores downloaded file
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
// 1
guard let sourceURL = downloadTask.originalRequest?.url else { return }
let download = downloadService.activeDownloads[sourceURL]
downloadService.activeDownloads[sourceURL] = nil
// 2
let destinationURL = localFilePath(for: sourceURL)
print(destinationURL)
// 3
let fileManager = FileManager.default
try? fileManager.removeItem(at: destinationURL)
do {
try fileManager.copyItem(at: location, to: destinationURL)
download?.track.downloaded = true
} catch let error {
print("Could not copy file to disk: \(error.localizedDescription)")
}
// 4
if let index = download?.track.index {
DispatchQueue.main.async {
self.tableView.reloadRows(at: [IndexPath(row: index, section: 0)], with: .none)
}
}
}

// Updates progress info
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask,
didWriteData bytesWritten: Int64, totalBytesWritten: Int64,
totalBytesExpectedToWrite: Int64) {
// 1
guard let url = downloadTask.originalRequest?.url,
let download = downloadService.activeDownloads[url] else { return }
// 2
download.progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
// 3
let totalSize = ByteCountFormatter.string(fromByteCount: totalBytesExpectedToWrite,
countStyle: .file)
// 4
DispatchQueue.main.async {
if let trackCell = self.tableView.cellForRow(at: IndexPath(row: download.track.index,
section: 0)) as? TrackCell {
trackCell.updateDisplay(progress: download.progress, totalSize: totalSize)
}
}
}

最佳答案

是的,基本思想是将 URLSessionDelegateUIViewController 解耦,并提供一种机制,URLSessionDelegate 可以通过该机制通知任何感兴趣的人在调用委托(delegate)方法时进行适当的更新。

我的首选模式是创建一个自定义共享 session 管理器,然后让它通知 View Controller (或发起下载的任何人)更新。有多种不同的机制可以通知 View Controller 您可以采用:

  • URLSessionDelegate 维护一个由任务标识符 (或 URL),例如:

    private var didWriteClosures: [Int: (URLSession, URLSessionDownloadTask, Int64, Int64, Int64) -> Void] = [:]
    private var didFinishClosures: [Int: (URLSession, URLSessionDownloadTask, URL) -> Void] = [:]

    当特定 View Controller 启动下载时,它会传递 session 管理器将保存在这些集合中的闭包。当主 session 管理器在 URLSessionDelegate 方法之一上获得回调时,它会获取任务标识符并有选择地调用正确的闭包。

  • 与上述方法类似,您可以在主 URLSessionDelegate 与发起请求的任何人之间采用您自己的委托(delegate)协议(protocol)模式。然后,主 URLSessionDelegate 可以维护这些委托(delegate)引用的集合,同样由任务标识符(或 URL)作为键控。

  • URLSessionDelegateNotificationCenter 上发布通知,然后让 View Controller 观察这些通知。

就个人而言,对于我只关心两个或三个委托(delegate)方法的简单接口(interface),我将使用第一种方法。当我怀疑我需要 URLSessionTaskDelegate 系列协议(protocol)的更大子集时,我倾向于使用第二种方法,然后我将采用委托(delegate)方法。

关于swift - 我们可以在 swift 中分别使用多个 UIViewController 中的 URLSessionDelegate 方法同时下载文件吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49542057/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com