从完成处理程序的 NSURLSession DownloadTaskWithRequest 获取数据
Get the data from NSURLSession DownloadTaskWithRequest from completion handler
所以我很难理解某些东西。这是我对 NSURSession 的理解:
一般来说,我有 2 个选项(据我所知)DataTask(e.x dataTaskWithRequest) 和 DownloadTask (e.x DownloadTaskWithRequest) - 使用他们的委托方法,或使用完成处理程序,不能两者都做。
我已经成功地使用 dataTaskWithRequest 接收数据,如下所示:
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()
效果很好。问题是我需要 DOWNLOAD 数据到磁盘,而不仅仅是内存(我正在下载图像)。所以我对 DownloadTaskWithRequest + 他的完成处理程序进行了相同的尝试,我注意到他采用的参数是相同的,除了第一个 NSURL在 DataTaskWithRequest 中是 NSData 所以它使事情变得非常简单。
例如
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()
我的问题是: 我知道我可以使用以下方法从 Location(NSURL) 中获取数据:
var data = NSData(contentsOfURL: location)
1) contentsOfURL 会不会让另一个 "request" 得到这个数据,或者他在本地工作?如果它再次发送请求,我该如何避免?
2)这是正确的方法吗(我知道我可以使用委托方法,但我不想这样做)?
3)我如何在本地存储我下载的数据(在回答问题 1 和 2 之后),并在需要时访问它?
谢谢大家!!抱歉新手问题,我真的很关心效率 - 谢谢!
在使用下载任务时,通常只需使用下载任务 completionHandler
提供的 location
即可将文件从临时位置移动到您选择的最终位置 (例如到 Documents 或 Cache 文件夹)使用 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()
您当然也可以使用 contentsOfURL
将对象加载到 NSData
中。是的,它适用于本地资源。而且,不,它不会发出另一个请求……如果您查看 URL,它是您本地文件系统中的一个文件 URL。但是这样你就失去了下载任务的大部分内存节省,所以如果你真的想把它放到 NSData
中,你可以使用数据任务。但是如果你想将它移动到持久存储,上面的模式可能是有意义的,完全避免使用 NSData
对象。
所以我很难理解某些东西。这是我对 NSURSession 的理解:
一般来说,我有 2 个选项(据我所知)DataTask(e.x dataTaskWithRequest) 和 DownloadTask (e.x DownloadTaskWithRequest) - 使用他们的委托方法,或使用完成处理程序,不能两者都做。 我已经成功地使用 dataTaskWithRequest 接收数据,如下所示:
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()
效果很好。问题是我需要 DOWNLOAD 数据到磁盘,而不仅仅是内存(我正在下载图像)。所以我对 DownloadTaskWithRequest + 他的完成处理程序进行了相同的尝试,我注意到他采用的参数是相同的,除了第一个 NSURL在 DataTaskWithRequest 中是 NSData 所以它使事情变得非常简单。 例如
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()
我的问题是: 我知道我可以使用以下方法从 Location(NSURL) 中获取数据:
var data = NSData(contentsOfURL: location)
1) contentsOfURL 会不会让另一个 "request" 得到这个数据,或者他在本地工作?如果它再次发送请求,我该如何避免?
2)这是正确的方法吗(我知道我可以使用委托方法,但我不想这样做)?
3)我如何在本地存储我下载的数据(在回答问题 1 和 2 之后),并在需要时访问它?
谢谢大家!!抱歉新手问题,我真的很关心效率 - 谢谢!
在使用下载任务时,通常只需使用下载任务 completionHandler
提供的 location
即可将文件从临时位置移动到您选择的最终位置 (例如到 Documents 或 Cache 文件夹)使用 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()
您当然也可以使用 contentsOfURL
将对象加载到 NSData
中。是的,它适用于本地资源。而且,不,它不会发出另一个请求……如果您查看 URL,它是您本地文件系统中的一个文件 URL。但是这样你就失去了下载任务的大部分内存节省,所以如果你真的想把它放到 NSData
中,你可以使用数据任务。但是如果你想将它移动到持久存储,上面的模式可能是有意义的,完全避免使用 NSData
对象。