是否可以使用 URL 会话委托方法进行进度和完成处理程序来完成?还是更好的选择?
Posted
技术标签:
【中文标题】是否可以使用 URL 会话委托方法进行进度和完成处理程序来完成?还是更好的选择?【英文标题】:Is it possible to use URL session delegate method for progress and completion handler for completion? Or better option? 【发布时间】:2020-04-20 05:23:32 【问题描述】:我正在使用我的下载器类通过 URLSession 委托方法下载文件,并使用委托方法的进度更新进度条。我从我的视图中这样调用下载类:
downloader.download(url: self.video.url, fileName: self.video.filePath)
完成后,我想更新视图中的一些变量以停止显示进度条。我正在考虑使用完成处理程序,但我认为这在使用委托进行进度和完成时不会真正起作用。而且我无法在下载器的完成委托方法中访问要更新的视图变量。
我想知道是否可以使用委托方法进行进度更新并使用完成处理程序来完成?这可能吗?
你有什么想法我可以做到吗?
这是我的下载器类:
class download: NSObject, URLSessionDelegate, URLSessionDownloadDelegate
@ObservedObject var globalScrollTitle: ScrollTitle = ScrollTitle.sharedInstance
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64)
let progress = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
DispatchQueue.main.async(execute:
self.globalScrollTitle.mainprogress = CGFloat(progress)
print(self.globalScrollTitle.mainprogress)
)
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL)
// check for and handle errors:
// * downloadTask.response should be an HTTPURLResponse with statusCode in 200..<299
print("download complete!")
do
let downloadedData = try Data(contentsOf: location)
DispatchQueue.main.async(execute:
print("transfer completion OK!")
let documentDirectoryPath = NSSearchPathForDirectoriesInDomains(.downloadsDirectory, .userDomainMask, true).first! as NSString
let destinationPath = documentDirectoryPath.appendingPathComponent((downloadTask.response?.suggestedFilename)!)
let pdfFileURL = URL(fileURLWithPath: destinationPath)
FileManager.default.createFile(atPath: pdfFileURL.path,
contents: downloadedData,
attributes: nil)
if FileManager.default.fileExists(atPath: pdfFileURL.path)
print("file present!") // Confirm that the file is here!
)
catch
print (error.localizedDescription)
func download(url: String, fileName: String)
let myUrl = URL(string: url)
let request = URLRequest(url:myUrl!)
//let config = URLSessionConfiguration.default
//let operationQueue = OperationQueue()
let session = URLSession(configuration: .default, delegate: self, delegateQueue: nil)
let downloadTask = session.downloadTask(with: request)
downloadTask.resume()
//completion()
【问题讨论】:
这能回答你的问题吗? get progress from dataTaskWithURL in swift 感谢您的帮助!我设法使用该链接找到了答案。 【参考方案1】:感谢 Faysal Ahmed,我设法找到了以下可行的解决方案。这让我可以在使用完成处理程序的同时跟踪更新 UI 的进度。
observation = task.progress.observe(\.fractionCompleted) progress, _ in
DispatchQueue.main.async(execute:
self.globalScrollTitle.mainprogress = CGFloat(progress.fractionCompleted)
)
if progress.fractionCompleted == 1
completion()
我的下载函数现在看起来像这样:
func download(url: String, fileName: String, completion: @escaping () -> Void)
let myUrl = URL(string: url)
let request = URLRequest(url:myUrl!)
let config = URLSessionConfiguration.default
let operationQueue = OperationQueue()
let session = URLSession(configuration: config, delegate: nil, delegateQueue: operationQueue)
let task = session.dataTask(with: request) (data, response, error) in
guard error == nil else
print(error!)
return
// Success
if let statusCode = (response as? HTTPURLResponse)?.statusCode
print("Success: \(statusCode)")
do
let documentFolderURL = try FileManager.default.url(for: .downloadsDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
let fileURL = documentFolderURL.appendingPathComponent(fileName)
try data!.write(to: fileURL)
DispatchQueue.main.async
if FileManager.default.fileExists(atPath: fileURL.path)
print("file present!") // Confirm that the file is here!
catch
print("error writing file \(error)")
observation = task.progress.observe(\.fractionCompleted) progress, _ in
DispatchQueue.main.async(execute:
self.globalScrollTitle.mainprogress = CGFloat(progress.fractionCompleted)
)
if progress.fractionCompleted == 1
completion()
task.resume()
【讨论】:
以上是关于是否可以使用 URL 会话委托方法进行进度和完成处理程序来完成?还是更好的选择?的主要内容,如果未能解决你的问题,请参考以下文章