调用AfterdidCompleteWithError时如何使用URLSession downloadTaskWithResumeData重新开始下载..?
Posted
技术标签:
【中文标题】调用AfterdidCompleteWithError时如何使用URLSession downloadTaskWithResumeData重新开始下载..?【英文标题】:How to use URLSession downloadTaskWithResumeData to start download again when AfterdidCompleteWithError Called..? 【发布时间】:2018-04-08 15:24:18 【问题描述】:我有从服务器下载两个文件并使用URLSession
(let dataTask = defaultSession.downloadTask(with: url)
) 将其存储到本地的代码。一切正常,唯一的问题是它正在下载第一个文件它给了我成功,但第二个文件没有完全下载..所以,我希望有一种方法可以重新下载第二个文件,它会给出错误..
我认为有办法做到这一点并开始研究它,我发现了这个委托方法..但没有太大帮助..如果失败,谁能帮我重新开始下载..我必须使用handleEventsForBackgroundURLSession 清除以前的下载..?
//当我获取文件名时将触发以下下载方法
func download(path: String?, filenames: [String]) -> Int
for filename in filenames
var downloadFrom = "ftp://" + username! + ":"
downloadFrom += password!.addingPercentEncoding(withAllowedCharacters: .urlPasswordAllowed)! + "@" + address!
if let downloadPort = port
downloadFrom += ":" + String(downloadPort) + "/"
else
downloadFrom += "/"
if let downloadPath = path
if !downloadPath.isEmpty
downloadFrom += downloadPath + "/"
downloadFrom += filename
if let url = URL(string: downloadFrom)
let dataTask = defaultSession.downloadTask(with: url)
dataTask.resume()
return DLResponseCode.success
请在下面找到委托方法..
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL)
var responseCode = DLResponseCode.success
// Move the file to a new URL
let fileManager = FileManager.default
let filename = downloadTask.originalRequest?.url?.lastPathComponent
let destUrl = cacheURL.appendingPathComponent(filename!)
do
let data = try Data(contentsOf: location)
// Delete it if it exists first
if fileManager.fileExists(atPath: destUrl.path)
do
try fileManager.removeItem(at: destUrl)
catch let error
danLogError("Clearing failed downloadFOTA file failed: \(error)")
responseCode = DLResponseCode.datalogger.failToCreateRequestedProtocolPipe
try data.write(to: destUrl)
catch
danLogError("Issue saving data locally")
responseCode = DLResponseCode.datalogger.noDataConnection
// Complete the download message
let message = DLBLEDataloggerChannel.Commands.download(responseCode: responseCode).description
connectionManagerDelegate?.sendMessageToDatalogger(msg: message)
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
if error == nil
print("session \(session) download completed")
else
print("session \(session) download failed with error \(String(describing: error?.localizedDescription))")
// session.downloadTask(withResumeData: <#T##Data#>)
guard error != nil else
return
danLogError("Session \(session) invalid with error \(String(describing: error))\n")
let responseCode = DLResponseCode.datalogger.failToCreateRequestedProtocolPipe
let message = DLBLEDataloggerChannel.Commands.download(responseCode: responseCode).description
connectionManagerDelegate?.sendMessageToDatalogger(msg: message)
// 当我调用 didWriteData 委托方法时,它在数据下方打印似乎没有下载完整的数据..
会话 <__nsurlsessionlocal:> 下载任务 <__nscflocaldownloadtask:> taskIdentifier: 2 running 在预期的 988980 字节中额外写入了 30028 字节(总共 988980 字节)。
//我为第二个文件收到的错误..这个错误有时会出现,但大多数时候会出现..
会话 <__nsurlsessionlocal:> 下载失败并出现错误 Optional("cancelled")
请帮我弄清楚..如果有什么方法可以在下载失败或失败后再次处理..
【问题讨论】:
向我们展示更多代码,否则您可能会得到冗长且可能充满假设的答案。如果这还不够糟糕,您可能会得到不考虑您的特定情况的替代解决方案。 我编辑并添加了代码.. 委托实现并不是特别有用。尽管它提供了您要做什么的基本概念,但向我们展示了您实际开始第一个下载任务的部分,然后是第二个失败的部分。为什么它会失败,你会得到什么错误? 我更新了问题请帮帮我.. 【参考方案1】:如果请求是可恢复的,恢复数据应该在 NSError 对象的 userInfo 字典中。
不幸的是,Apple 似乎完全废弃了 NSURLSession 的编程指南(或者至少我在 Google 搜索结果中找不到),并且参考中的替换内容缺少 all 的讨论如何进行正确的错误处理的部分(即使您正在寻找的常量也丢失了),所以我将不得不在查看标题的帮助下从内存中描述它。艾克。
您要查找的密钥是NSURLSessionDownloadTaskResumeData
。
如果该键存在,它的值是一个小的 NSData blob。存储它,然后使用 Reachability API(使用该请求 URL 中的实际主机名)来决定何时重试请求。
在 Reachability 告诉您服务器可达后,使用恢复数据创建一个新的下载任务并启动它。
【讨论】:
关于它的文档现在在这里(至少在我发表评论时在这里):developer.apple.com/documentation/foundation/url_loading_system/… 感谢您的链接。以上是关于调用AfterdidCompleteWithError时如何使用URLSession downloadTaskWithResumeData重新开始下载..?的主要内容,如果未能解决你的问题,请参考以下文章