在iphone中下载图像时,在UIProgressView中显示准确的进度

时间:2013-03-15 13:41:17

标签: iphone ios objective-c xcode ipad

我有四个包含图片的网址... 我正在将这些图像下载并将它们放入文档文件夹中。

这是我的代码..

-(void)viewDidLoad
{
NSMutableArray *myUrlsArray=[[NSMutableArray alloc]init];
[myUrlsArray addObject:@"http://blogs.sfweekly.com/thesnitch/steve_jobs3.jpg"];
[myUrlsArray addObject:@"http://www.droid-life.com/wp-content/uploads/2012/12/Steve-Jobs-Apple.jpg"];
[myUrlsArray addObject:@"http://2.bp.blogspot.com/-T6nbl0rQoME/To0X5FccuCI/AAAAAAAAEZQ/ipUU7JfEzTs/s1600/steve-jobs-in-time-magazine-front-cover.png"];
[myUrlsArray addObject:@"http://images.businessweek.com/ss/08/09/0929_most_influential/image/steve_jobs.jpg"];
[myUrlsArray addObject:@"http://cdn.ndtv.com/tech/gadget/image/steve-jobs-face.jpg"];

for (int i=0; i<myUrlsArray.count; i++)
{
    [self downloadImageFromURL:[myUrlsArray objectAtIndex:i] withName:[NSString stringWithFormat:@"MyImage%i.jpeg",i]];
}

}




#pragma mark- downloading File

-(void)downloadImageFromURL:(NSString *)myURLString withName:(NSString *)fileName
{
UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:myURLString]]];

NSLog(@"%f,%f",image.size.width,image.size.height);

   // Let's save the file into Document folder.**

    NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) objectAtIndex:0];

NSString *jpegPath = [NSString stringWithFormat:@"%@/%@",documentsPath,fileName];// this path if you want save reference path in sqlite
NSData *data2 = [NSData dataWithData:UIImageJPEGRepresentation(image, 1.0f)];//1.0f = 100% quality
[data2 writeToFile:jpegPath atomically:YES];

}

现在......我需要准确显示UIProgressView以便上面的下载进度。

如何实现此功能......

任何人都可以提供一些指导方针来实现这一目标。

提前致谢...

4 个答案:

答案 0 :(得分:2)

您对dataWithContentsOfURL的调用是同步的,这意味着您在下载过程中无法获得更新。

您可以使用像AFNetworking(https://github.com/AFNetworking/AFNetworking)这样的库,它可以回调下载进度。

答案 1 :(得分:2)

实际上更好的解决方案是使用SDWebImage管理器,它将为您加载背景中的图像并缓存它们。然后,下次使用该图像时,它将检查缓存。谷歌吧。

这样,当你下载东西时,用户也不必坐着等待..

然后看看另外一个关于如何处理状态的问题:

How to show an activity indicator in SDWebImage

答案 2 :(得分:2)

不要使用dataWithContentsOfURL,在数据到达之前阻塞主线程。

而是使用NSURLConnection创建自己的连接,然后开始聆听您的代理人。

  • connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response:使用[response expectedContentLength]获取总数据大小。
  • connection:(NSURLConnection *)connection didReceiveData:(NSData *)data:这是您进行计算并更新UIProgressView的地方。像loadingBytes /总数据大小。
祝你好运。

答案 3 :(得分:2)

我建议您使用一些异步下载技术(AFNetworking,SDWebImage,或者使用基于委托的NSURLSession)而不是dataWithContentsOfURL,以便(a)不阻止主队列; (b)随着下载的进行,您可以获得进度更新。

我还建议为每次下载创建一个NSProgress。当您的委托方法获取有关已下载的字节数的更新时,请更新NSProgress对象。

然后,您可以将每个NSProgressobservedProgress关联UIProgressView,当您更新NSProgress时,可以自动更新用户界面。

或者,如果您和单个UIProgressView显示每次下载的所有NSProgress的总进度,则可以创建父NSProgress,建立每个下载的{{1}作为父NSProgress的孩子,然后,当每次下载更新其各自的NSProgress时,这将自动触发父NSProgress的计算。同样,您可以将该父NSProgress绑定到主NSProgress,并且只需让每个下载更新其个人UIProgressView,您就会自动使用总进度更新UI。 / p>


但是,有一个技巧,因为有些Web服务不会通知您预期的字节数。他们将报告NSProgress的“预期字节数”,即-1! (有合理的理由说明为什么它可能超出了这个问题的范围。)这显然很难计算下载的百分比。

在这种情况下,有几种方法:

  1. 您可以举手并使用不确定的进度指示器;

  2. 您可以尝试更改请求,以便Web服务报告有意义的“预期字节数”值(例如https://stackoverflow.com/a/22352294/1271826);或

  3. 您可以使用“估计下载大小”来估算完成百分比。例如,如果您知道您的图片平均每个100kb,您可以执行以下操作来更新与特定下载相关联的NSURLResponseUnknownLength

    NSProgress

    使用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; 函数返回“完成百分比”值,使用tanh作为估算的基础,可以平滑地渐近逼近100%,这有点狡猾。

    这并不完美,但它会为完成百分比提供相当不错的代理。