当app强制退出时如何恢复下载?

时间:2015-12-07 11:19:20

标签: ios download resume application-restart

我的应用必须下载一个非常大的文件(390Mb), 我正在使用TCBlopDownloadSwift进行下载(我将其转换为swift 2.0并且工作正常)我将配置为后台下载。 我想,当app强制退出时能够恢复下载。 我发现当应用程序退出时,我仍然可以在缓存中找到下载的数据(在“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
}

它返回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表示无法写入文件

我看过很多帖子,却找不到答案

最有希望的是https://forums.developer.apple.com/thread/24770

1 个答案:

答案 0 :(得分:3)

好的,问题来自图书馆,我解释一下:

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返回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)
        }
    }
}

我不得不销毁库(如果app强制退出,它的结构不允许恢复下载)

<强> TLDR

如果您使用具有自定义委托的库(一个不同于NSURLSessionDelegate),问题可能来自不调用URLSession的自定义委托(会话:NSURLSession,任务:NSURLSessionTask,didCompleteWithError sessionError:NSError?)方法< / p>

PS:感谢您的理解,我理解我的帖子有多误导。

我会尝试(如果我有时间)处理一个框架,该框架可以允许在app force-Quit之后恢复下载(看起来很简单,实际上你只需要为该特定情况添加委托方法但是如果它更复杂我没有时间,可能稍后)