我有从服务器下载两个文件并使用URLSession
将其存储到本地的代码(let dataTask = defaultSession.downloadTask(with: url)
)。一切都工作正常,唯一的问题是它正在下载第一个文件,它给了我成功,但第二个文件没有完全下载。所以,我希望有一种方法可以重新启动第二个文件的下载,但会出现错误..
我认为有办法做到这一点并开始研究它,我发现了这个委托(delegate)方法..但没有太大帮助..任何人都可以帮我解决如果失败如何重新启动下载..我必须使用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
}
请在下面找到委托(delegate)方法..
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 委托(delegate)方法时,它在下面打印数据似乎没有下载完整的数据..
session <__NSURLSessionLocal: 0x103e37970> 下载任务 <__NSCFLocalDownloadTask: 0x108d2ee60>{ taskIdentifier: 2 } { running } 在预期的 988980 字节中额外写入了 30028 字节(总计 988980 字节)。
//我收到第二个文件的错误..此错误有时会出现,但并非总是如此,但大多数时候都会出现..
session <__NSURLSessionLocal: 0x103e37970> 下载失败,错误为可选(“已取消”)
请帮我弄清楚..如果有任何方法可以在下载失败后再次处理下载或失败的原因..
最佳答案
如果请求可恢复,则恢复数据应位于 NSError 对象的 userInfo 字典中。
不幸的是,Apple 似乎已经完全废弃了 NSURLSession 的编程指南(或者至少我在 Google 搜索结果中找不到它),并且引用中的替换内容缺少全部讨论如何进行正确的错误处理的部分(甚至您正在寻找的常量丢失了),因此我将不得不借助查看标题从内存中描述这一切。恶心。
您要查找的 key 是NSURLSessionDownloadTaskResumeData
。
如果该键存在,则其值是一个小的 NSData blob。存储该信息,然后使用 Reachability API(使用该请求 URL 中的实际主机名)来决定何时重试该请求。
在 Reachability 告诉您服务器可以访问后,使用恢复数据创建一个新的下载任务并启动它。
关于objective-c - 当 AfterdidCompleteWithError 调用时,如何使用 URLSession downloadTaskWithResumeData 再次开始下载..?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49719476/