从完成处理程序中获取NSURLSession DownloadTaskWithRequest中的数据

Jac*_*ite 9 nsdata ios nsurlsession nsurlsessiondownloadtask swift

所以我很难理解某些东西.这是我对NSURSession的理解:

  • 一般来说,我有2个选项(据我所知)DataTask(ex dataTaskWithRequest)DownloadTask(ex DownloadTaskWithRequest) - 使用他们的委托方法,使用完成处理程序,不能两者兼顾.我已经设法使用dataTaskWithRequest接收DATA,如下所示:

    let request = NSMutableURLRequest(URL: dataSourceURL!)
    request.HTTPMethod = "POST"
    
    let postString = "lastid=\(id)"
    request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
        data, response, error in
    
        if error != nil {
            println("error=\(error)")
            return
        }
        if data != nil {
            println("works")
            //Handle data
    
    
        }
        //println("response = \(response)")
    
    
    }
    task.resume()      
    
    Run Code Online (Sandbox Code Playgroud)

它完美地运作.问题是我需要将数据下载到磁盘而不是下载到内存(我正在下载图像).所以我尝试使用DownloadTaskWithRequest +他的完成处理程序,我注意到他所采用的参数是相同的,期望第一个是NSURL,而DataTaskWithRequestNSData,因此它使事情变得非常简单.恩.

 let task2 = NSURLSession.sharedSession().downloadTaskWithRequest(request, completionHandler: { (location : NSURL!, response : NSURLResponse!, error : NSError?) -> Void in
            if error != nil {
                return
            }

            //How do I get the data??
        })
task2.resume()
Run Code Online (Sandbox Code Playgroud)

我的问题是:我知道我可以使用以下方法从位置(NSURL)中获取DATA:

    var data = NSData(contentsOfURL: location)
Run Code Online (Sandbox Code Playgroud)

1)contentsOfURL会使另一个"请求"获取此数据,还是他在本地工作?如果再次发送请求,我该如何避免呢?

2)这是正确的方法(我知道我可以使用委托方法,我不喜欢)?

3)如何在本地存储我已下载的数据(在问题1和2回答之后),并在需要时访问它?

感谢你们!!对不起新手问题,我真的非常关心高效 - 谢谢!

Rob*_*Rob 14

当使用下载任务,一般人会简单地使用location提供由completionHandler下载任务的简单的把文件从临时位置移动到你所选择的(该文件或缓存文件夹如)使用最终位置NSFileManager.

let task = NSURLSession.sharedSession().downloadTaskWithURL(url) { location, response, error in
    guard location != nil && error == nil else {
        print(error)
        return
    }

    let fileManager = NSFileManager.defaultManager()
    let documents = try! fileManager.URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)
    let fileURL = documents.URLByAppendingPathComponent("test.jpg")
    do {
        try fileManager.moveItemAtURL(location!, toURL: fileURL)
    } catch {
        print(error)
    }
}
task.resume()
Run Code Online (Sandbox Code Playgroud)

您当然也可以将对象加载到NSData使用中contentsOfURL.是的,它适用于本地资源.并且,不,它不会发出另一个请求...如果您查看URL,它是本地文件系统中的文件URL.但是你以这种方式损失了下载任务的大部分内存节省,所以你可能会使用数据任务,如果你真的想把它变成一个NSData.但是如果你想将它移动到持久存储,上面的模式可能是有意义的,NSData完全避免使用对象.