I have four urls which consists images... I\'m downloding those images and placing them into documents folder..
here is my code..
I'd suggest you use some asynchronous downloading technique (either AFNetworking, SDWebImage, or roll your own with delegate-based NSURLSession
) rather than dataWithContentsOfURL
so that (a) you don't block the main queue; and (b) you can get progress updates as the downloads proceed.
I'd also suggest creating a NSProgress for each download. When your delegate method gets updates about how many bytes have been downloaded, update the NSProgress
object.
You then can associate each NSProgress
with a observedProgress for a UIProgressView, and when you update your NSProgress
, the UI can be updated automatically.
Or, if you and a single UIProgressView
to show the aggregate progress of all of the NSProgress
for each download, you can create a parent NSProgress
, establish each download's NSProgress
as a child of the parent NSProgress
, and then, as each download updates its respective NSProgress
, this will automatically trigger the calculation of the parent NSProgress
. And again, you can tie that parent NSProgress
to a master UIProgressView
, and you'll automatically update the UI with the total progress, just by having each download update its individual NSProgress
.
There is a trick, though, insofar as some web services will not inform you of the number of bytes to be expected. They'll report an "expected number of bytes" of NSURLResponseUnknownLength
, i.e. -1! (There are logical reasons why it does that which are probably beyond the scope of this question.) That obviously makes it hard to calculate what percentage has been downloaded.
In that case, there are a few approaches:
You can throw up your hands and just use an indeterminate progress indicator;
You can try changing the request such that web service will report meaningful "expected number of bytes" values (e.g. https://stackoverflow.com/a/22352294/1271826); or
You can use an "estimated download size" to estimate the percentage completion. For example, if you know your images are, on average, 100kb each, you can do something like the following to update the NSProgress
associated with a particular download:
if (totalBytesExpectedToWrite >= totalBytesWritten) {
self.progress.totalUnitCount = totalBytesExpectedToWrite;
} else {
if (totalBytesWritten <= 0) {
self.progress.totalUnitCount = kDefaultImageSize;
} else {
double written = (double)totalBytesWritten;
double percent = tanh(written / (double)kDefaultImageSize);
self.progress.totalUnitCount = written / percent;
}
}
self.progress.completedUnitCount = totalBytesWritten;
This is a bit of sleight of hand that uses the tanh
function to return a "percent complete" value that smoothly and asymptotically approaches 100%, using the kDefaultImageSize
as the basis for the estimation.
It's not perfect, but it yields a pretty decent proxy for percent completion.
Do not use dataWithContentsOfURL
, you are blocking the main thread until the data arrives.
Instead create your own connection with NSURLConnection
and start listening to your delegate.
connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
: get the total data size with [response expectedContentLength]
.connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
: This is where you do your calculations and update your UIProgressView
. Something like, loadedBytes/total data size.Good luck.
Your call to dataWithContentsOfURL is synchronous, meaning you don't get updates as the download is in process.
You can use a library like AFNetworking (https://github.com/AFNetworking/AFNetworking) which has callbacks to the progress of the download.
Actually a better solution is to use SDWebImage manager which will load the images in the background for you and cache them. Then the next time you use that image it will check the cache. Google it.
That way the user also doesn't have to sit around and wait while you're downloading stuff..
Then look at this other question that has some ideas on how to do a status:
How to show an activity indicator in SDWebImage