ASIHTTPRequest系列(二):文件下载

四、下载

1、简单下载

打开IB,拖入一个Progress View,在源文件中声明为IBOutlet,然后进行连接。

-(IBAction)goURL{

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

path=[pathstringByAppendingPathComponent:@"plsqldev714.rar"];

NSURL*url = [NSURLURLWithString:@"http://localhost/upload/plsqldev714.rar"];

ASIHTTPRequest*request = [ASIHTTPRequestrequestWithURL:url];

[requestsetDownloadDestinationPath:path];

[requestsetDownloadProgressDelegate:progressView];

[requeststartSynchronous];

}

运行程序,下载进度会在progress view中显示。下载进度显示当前完成的大约比例。

2、使用队列下载并显示进度条

队列是指NSOperationQueue 对象,其实是一种多线程操作,可以同时执行多个下载任务,甚至多线程下载同一任务(当然需要服务器支持,把同一个文件资源分成多个线程同时下载,最后再合并为一个文件)。下面的例子里我们使用了 NSOperationQueue 同时进行多个下载任务,同时,Progress View显示精确进度。

这个例子需要对界面进行一些设计。为简便,我们使用IB 设计界面。

新建一个ViewController类。Add->New File,选择UIViewController subclass,并勾上“With XIB for user interface”,命名为 QueueViewController。

用IB 打开 Xib 文件,在其中拖入6个UILable、1个UIButton和3个UIProgressView:

ASIHTTPRequest系列(二):文件下载

在Xcode中声明必要的变量和 IBOutlet/IBAction:

#import<UIKit/UIKit.h>

#import"ASIHTTPRequest.h"

#import"ASINetworkQueue.h"

@interfaceQueueViewController : UIViewController {

ASINetworkQueue*networkQueue;

UILabel*status_total,*status_file1,*status_file2;

UIButton*button;

UIProgressView*progress_total,*progress_file1,*progress_file2;

boolfailed;

NSFileManager*fm;

}

@property(nonatomic,retain)IBOutletUILabel *status_file2,*status_file1,*status_total;

@property(nonatomic,retain)IBOutletUIButton *button;

@property(nonatomic,retain)IBOutletUIProgressView *progress_file1,*progress_file2,*progress_total;

-(IBAction)go:(id)sender;

@end

将所有出口正确地连接到QueueViewController.xib 中,保存。

打开MainWindow.xib,拖一个UIViewController进去并将其Identifier改为QueueViewController,再将它连接到Window对象的的rootViewController。

编写UIButton 的 Touch up inside 事件代码如下:

-(IBAction)go:(id)sender{

if(fm==nil) {

fm=[NSFileManagerdefaultManager];

}

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

//文件1

NSString* file1=@"image.png";

NSURL*url1 = [NSURLURLWithString:@"http://220.163.103.23/interface/GetAttach?Accounts=sa&[email protected]&AttachID=26"];

//先创建文件file1,再用NSFileHandle打开它

NSString*path1=[userDocPathstringByAppendingPathComponent:file1];

boolb=[fmcreateFileAtPath:path1contents:nilattributes:nil];

NSFileHandle*fh1;

__blockuintfSize1=0;//B为单位,记录已下载的文件大小,需要声明为块可写

if(b){

fh1=[NSFileHandlefileHandleForWritingAtPath:path1];

}

//文件2

NSString* file2=@"plsqldev714.rar";

NSURL*url2 = [NSURLURLWithString:@"http://220.163.103.23/upload/plsqldev714.rar"];

//先创建文件file2,再用NSFileHandle打开它

NSString*path2=[userDocPathstringByAppendingPathComponent:file2];

b=[fmcreateFileAtPath:path2contents:nilattributes:nil];

NSFileHandle*fh2;

__blockuintfSize2=0;//B为单位,记录已下载的文件大小,需要声明为块可写

if(b){

fh2=[NSFileHandlefileHandleForWritingAtPath:path2];

}

////////////////////////////任务队列/////////////////////////////

if(!networkQueue) {

networkQueue= [[ASINetworkQueuealloc]init];

}

failed=NO;

[networkQueuereset];//队列清零

[networkQueuesetDownloadProgressDelegate:progress_total];//设置queue进度条

[networkQueuesetShowAccurateProgress:YES];//进度精确显示

[networkQueuesetDelegate:self];//设置队列的代理对象

ASIHTTPRequest*request;

///////////////// request for file1 //////////////////////

request = [ASIHTTPRequestrequestWithURL:url1];//设置文件1url

[requestsetDownloadProgressDelegate:progress_file1];//文件1的下载进度条

//设置userInfo,可用于识别不同的request对象

[requestsetUserInfo:[NSDictionarydictionaryWithObject:file1forKey:@"TargetPath"]];

//使用complete块,在下载完时做一些事情

[requestsetCompletionBlock:^(void){

NSLog(@"%@ complete !",file1);

assert(fh1);

//关闭file1

[fh1closeFile];

}];

//使用failed块,在下载失败时做一些事情

[requestsetFailedBlock:^(void){

NSLog(@"%@ download failed !",file1);}

];

//使用received块,在接受到数据时做一些事情

[requestsetDataReceivedBlock:^(NSData* data){

fSize1+=data.length;

[status_file1setText:[NSStringstringWithFormat:@"%.1f K",fSize1/1000.0]];

[status_totalsetText:[NSStringstringWithFormat:@"%.0f %%",progress_total.progress*100]];

if(fh1!=nil) {

[fh1seekToEndOfFile];

[fh1writeData:data];

}

NSLog(@"%@:%u",file1,data.length);

}];

[networkQueueaddOperation:request];

///////////// request for file2 //////////////////

request = [[[ASIHTTPRequestalloc]initWithURL:url2]autorelease];//设置文件2url

[requestsetDownloadProgressDelegate:progress_file2];//文件2的下载进度条

[requestsetUserInfo:[NSDictionarydictionaryWithObject:file2forKey:@"TargetPath"]];

//使用complete块,在下载完时做一些事情

[requestsetCompletionBlock:^(void){

NSLog(@"%@ complete !",file2);

assert(fh2);

//关闭file2

[fh2closeFile];

}];

//使用failed块,在下载失败时做一些事情

[requestsetFailedBlock:^(void){

NSLog(@"%@ download failed !",file2);

}];

//使用received块,在接受到数据时做一些事情

[requestsetDataReceivedBlock:^(NSData* data){

fSize2+=data.length;

[status_file2setText:[NSStringstringWithFormat:@"%.1f K",fSize2/1000.0]];

[status_totalsetText:[NSStringstringWithFormat:@"%.0f %%",progress_total.progress*100]];

if(fh2!=nil) {

[fh2seekToEndOfFile];

[fh2writeData:data];

}

}];

[networkQueueaddOperation:request];

[networkQueuego];//队列任务开始

}

运行效果如下:

ASIHTTPRequest系列(二):文件下载