问题
I know I can use dataTaskWithURL:completionHandler:
to get the data in the completionHandler block, but that blocks the delegate methods from firing, and I need the didReceiveData:
method to fire, as it's how I configure my progress indicator.
I'm completely at a loss how to get the downloaded data once it's complete. What's the delegate method equivalent of the completion block? didCompleteWithError
doesn't seem to return any NSData
.
I don't have to manually piece the data together in didReceiveData
, do I? That seems really lame when the completionHandler just hands it off to you. I wouldn't mind doing that if it weren't for the fact that I could be downloading 50+ things at once, so keeping track of all that partial data seems like a pain in the ass. Should I just switch to NSURLSessionDownloadTask
?
回答1:
Yes, you have to manually piece the data together (or you can stream it to a file if it's really big and you don't want it taking up memory).
So, didReceiveData
method will be returning your data as it comes in. So you should have instantiated a NSMutableData
(for example, in didReceiveResponse
) to which didReceiveData
will append the data as it comes in. When didCompleteWithError
is called, assuming the error is nil
, you can be confident that your NSMutableData
now contains all of the data received. As you noted, the challenge is keeping track of all of the 50+ downloads, so I maintain an dictionary keyed by task identifiers to keep track of which to append the data to. (Personally, I think it's a design flaw that NSURLSession
implements the task, download, and upload delegates at the session level, rather than letting us instantiate separate task delegate objects for each task. But we're stuck with what we've got.)
If you're just downloading the data, the NSURLSessionDownloadTask
is a great alternative (and is more efficient in terms of memory usage than just appending to NSMutableData
instances), and you can conceivably also use a background session if you want (which you can't with a NSURLSessionDataTask
).
Finally, if you're really doing 50+ downloads, you might want to consider wrapping the download tasks in NSOperation
subclass so you can constrain how many run concurrently without risking having any timeout.
来源:https://stackoverflow.com/questions/21924483/how-do-i-get-the-data-from-a-finished-nsurlsessiondatatask