应用程序强制退出时如何恢复下载?
How to resume a download when the app force-Quit?
我的应用程序必须下载一个相当大的文件(390Mb),
我正在使用 TCBlopDownloadSwift 进行下载(我将其转换为 swift 2.0,并且工作正常)并且我为后台下载进行了配置。
我想,当应用程序强制退出时能够恢复下载。
我发现当应用程序退出时,我仍然可以在缓存中(在 "com.apple.nsurlsessiond/Downloads/" + bundleIdentifier 中)找到作为 tmp 文件下载的数据。
但是当我尝试使用 :
获取下载数据时
func dataInCacheForName (name : String) -> NSData? {
let PathToCache = (NSSearchPathForDirectoriesInDomains( NSSearchPathDirectory.CachesDirectory , .UserDomainMask, true)[0] as NSString).stringByAppendingPathComponent("com.apple.nsurlsessiond/Downloads/" + bundleIdentifier)
let path = (PathToCache as NSString).stringByAppendingPathComponent(name)
let data = NSData(contentsOfFile: path)
print("data : \(data?.length)")
return data
}
它 returns nil ,但文件不是 nil 。我可以移动文件,所以我尝试移动文档中的文件。但是如果我尝试使用数据恢复下载,我会收到错误消息:
-[NSKeyedUnarchiver initForReadingWithData:]: data is NULL
-[NSKeyedUnarchiver initForReadingWithData:]: data is NULL
-[NSKeyedUnarchiver initForReadingWithData:]: data is NULL
后台下载的简历数据无效。后台下载必须使用 http 或 https,并且必须下载到可访问的文件。
并且在 URLSession
(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError sessionError: NSError?)
error userInfo : Optional([:])
: Optional(Error Domain=NSURLErrorDomain Code=-3003 "(null)")
错误代码-3003表示无法写入文件
我已经阅读了很多 post 却找不到答案
好的,问题出在图书馆,我解释一下:
TCBlobDownloadSwift 有一个自定义委托,它在 urlSessionDelegate 方法的末尾调用(例如自定义委托给出进度值而不是 totalByteWritten 和 totalBytesExpectedToWrite)。 :
func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
guard let download = self.downloads[downloadTask.taskIdentifier] else{
return
}
let progress = totalBytesExpectedToWrite == NSURLSessionTransferSizeUnknown ? -1 : Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
print("progress : \(progress)")
// the delegate is in fact called download and has more parameter .
customDelegate(download , progress : progress)
}
而且效果很好。但是当应用程序重新启动时恢复下载时未注册下载并且 downloadTask.taskIdentifier return nil 因此未调用自定义委托!
为了在强制退出后恢复下载,您必须使用此代码(当创建遵循 NSURLSessionDelegate 协议的对象时调用该方法):
public func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError sessionError: NSError?) {
if let error = sessionError {
print("error : \(error)")
let directory = NSURL(fileURLWithPath: fileManage.Path)
if let resumedData = error.userInfo[NSURLSessionDownloadTaskResumeData] as? NSData {
let url = error.userInfo[NSURLErrorFailingURLStringErrorKey] as? String
// get name from url just read a dictionnary of name and url
let name = getNameFromURL(url!)
// start the download
self.manager.downloadFileWithResumeData(resumedData, toDirectory: directory , withName: name, andDelegate: self)
}
}
}
我不得不销毁库(如果应用强制退出,它的结构不允许恢复下载)
TLDR
如果您使用带有自定义委托(与 NSURLSessionDelegate 不同)的库,则问题可能出自不调用 URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError sessionError: NSError?) 的自定义委托。方法
PS:感谢您的回答,我明白我的 Post 是多么具有误导性。
我会尝试(如果我有时间)开发一个允许在应用程序强制退出后恢复下载的框架(它看起来很简单,实际上你只需要为特定情况添加一个委托方法但如果它更复杂,我可能还没有时间)
我的应用程序必须下载一个相当大的文件(390Mb), 我正在使用 TCBlopDownloadSwift 进行下载(我将其转换为 swift 2.0,并且工作正常)并且我为后台下载进行了配置。 我想,当应用程序强制退出时能够恢复下载。 我发现当应用程序退出时,我仍然可以在缓存中(在 "com.apple.nsurlsessiond/Downloads/" + bundleIdentifier 中)找到作为 tmp 文件下载的数据。 但是当我尝试使用 :
获取下载数据时func dataInCacheForName (name : String) -> NSData? {
let PathToCache = (NSSearchPathForDirectoriesInDomains( NSSearchPathDirectory.CachesDirectory , .UserDomainMask, true)[0] as NSString).stringByAppendingPathComponent("com.apple.nsurlsessiond/Downloads/" + bundleIdentifier)
let path = (PathToCache as NSString).stringByAppendingPathComponent(name)
let data = NSData(contentsOfFile: path)
print("data : \(data?.length)")
return data
}
它 returns nil ,但文件不是 nil 。我可以移动文件,所以我尝试移动文档中的文件。但是如果我尝试使用数据恢复下载,我会收到错误消息:
-[NSKeyedUnarchiver initForReadingWithData:]: data is NULL
-[NSKeyedUnarchiver initForReadingWithData:]: data is NULL
-[NSKeyedUnarchiver initForReadingWithData:]: data is NULL
后台下载的简历数据无效。后台下载必须使用 http 或 https,并且必须下载到可访问的文件。
并且在 URLSession
(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError sessionError: NSError?)
error userInfo : Optional([:])
: Optional(Error Domain=NSURLErrorDomain Code=-3003 "(null)")
错误代码-3003表示无法写入文件
我已经阅读了很多 post 却找不到答案
好的,问题出在图书馆,我解释一下:
TCBlobDownloadSwift 有一个自定义委托,它在 urlSessionDelegate 方法的末尾调用(例如自定义委托给出进度值而不是 totalByteWritten 和 totalBytesExpectedToWrite)。 :
func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
guard let download = self.downloads[downloadTask.taskIdentifier] else{
return
}
let progress = totalBytesExpectedToWrite == NSURLSessionTransferSizeUnknown ? -1 : Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
print("progress : \(progress)")
// the delegate is in fact called download and has more parameter .
customDelegate(download , progress : progress)
}
而且效果很好。但是当应用程序重新启动时恢复下载时未注册下载并且 downloadTask.taskIdentifier return nil 因此未调用自定义委托!
为了在强制退出后恢复下载,您必须使用此代码(当创建遵循 NSURLSessionDelegate 协议的对象时调用该方法):
public func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError sessionError: NSError?) {
if let error = sessionError {
print("error : \(error)")
let directory = NSURL(fileURLWithPath: fileManage.Path)
if let resumedData = error.userInfo[NSURLSessionDownloadTaskResumeData] as? NSData {
let url = error.userInfo[NSURLErrorFailingURLStringErrorKey] as? String
// get name from url just read a dictionnary of name and url
let name = getNameFromURL(url!)
// start the download
self.manager.downloadFileWithResumeData(resumedData, toDirectory: directory , withName: name, andDelegate: self)
}
}
}
我不得不销毁库(如果应用强制退出,它的结构不允许恢复下载)
TLDR
如果您使用带有自定义委托(与 NSURLSessionDelegate 不同)的库,则问题可能出自不调用 URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError sessionError: NSError?) 的自定义委托。方法
PS:感谢您的回答,我明白我的 Post 是多么具有误导性。
我会尝试(如果我有时间)开发一个允许在应用程序强制退出后恢复下载的框架(它看起来很简单,实际上你只需要为特定情况添加一个委托方法但如果它更复杂,我可能还没有时间)