2

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

这是我的代码..

-(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

4 回答 4

2

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

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

于 2013-03-15T13:49:13.883 回答
2

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

这样用户也不必在您下载内容时坐下来等待..

然后看看这个对如何做一个状态有一些想法的另一个问题:

如何在 SDWebImage 中显示活动指示器

于 2013-03-15T14:02:10.190 回答
2

不要使用dataWithContentsOfURL,您正在阻塞主线程,直到数据到达。

而是创建您自己的连接NSURLConnection并开始聆听您的代表。

  • connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response: 获取总数据大小[response expectedContentLength]
  • connection:(NSURLConnection *)connection didReceiveData:(NSData *)data:这是您进行计算并更新您的UIProgressView. 比如,loadedBytes/总数据大小。

祝你好运。

于 2013-03-15T14:07:43.843 回答
2

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

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

然后,您可以将每个NSProgress与 aobservedProgress相关联UIProgressView,并且当您更新您NSProgress的 时,UI 可以自动更新。

或者,如果你和一个单UIProgressView显示所有下载的总进度NSProgress,你可以创建一个父级NSProgress,将每个下载的建立为父NSProgress级的子级NSProgress,然后,随着每个下载更新其各自的NSProgress,这将自动触发父级的计算NSProgress。同样,您可以将该父级绑定NSProgress到一个 master UIProgressView,并且您将自动更新 UI 的总进度,只需让每个下载更新其单独的NSProgress.


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

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

  1. 您可以举起双手,只使用不确定的进度指示器;

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

  3. 您可以使用“估计下载大小”来估计完成百分比。例如,如果您知道您的图像平均为 100kb,您可以执行以下操作来更新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%,使用kDefaultImageSize作为估计的基础。

    它并不完美,但它产生了一个相当不错的完成百分比代理。

于 2013-03-15T15:23:47.047 回答