ASIHTTPRequest下载之断点续传
使用iOS SDK中的HTTP网络请求API,相当的复杂,调用很繁琐,ASIHTTPRequest就是一个对CFNetwork API进行了封装,并且使用起来非常简单的一套API,用Objective-C编写,可以很好的应用在Mac OS X系统和iOS平台的应用程序中。ASIHTTPRequest适用于基本的HTTP请求,和基于REST的服务之间的交互。
导入第三方ASIHTTPRequset文件后,需要添加某些类库
再添加-fno-objc-arc使它不检测ARC
导入ASIHTTPRequest.h文件后:
1 #import <UIKit/UIKit.h> 2 #import "ASIHTTPRequest.h" 3 @interface RootViewController : UIViewController 4 { 5 //声明请求对象 6 ASIHTTPRequest *request; 7 } 8 @property (strong, nonatomic) IBOutlet UIProgressView *process_UpLoad; 9 - (IBAction)btn_Start:(UIButton *)sender; 10 - (IBAction)btn_Pause:(UIButton *)sender; 11 @end
1 - (IBAction)btn_Start:(UIButton *)sender { 2 NSString *strUrl=@"http://121.41.88.127:8080/zhangchu/HandheldKitchen/ipad/20141227135528915.jpg"; 3 //具体下载功能 4 NSURL *URL=[NSURL URLWithString:strUrl]; 5 request=[[ASIHTTPRequest alloc] initWithURL:URL]; 6 //获取沙盒路径。NSHomeDirectory获取的就是沙盒路径 7 NSString *sandPath=[NSHomeDirectory() stringByAppendingString:@"/Documents"]; 8 NSLog(@"%@",sandPath); 9 //确定缓存路径 10 NSString *tempPath=[NSString stringWithFormat:@"%@/temp",sandPath]; 11 //确定下载文件的路径 12 NSString *downPath=[NSString stringWithFormat:@"%@/down.jpg",sandPath]; 13 //设置下载文件的路径 14 [request setDownloadDestinationPath:downPath]; 15 //设置缓存路径 16 [request setTemporaryFileDownloadPath:tempPath]; 17 //设置进度条 18 [request setDownloadProgressDelegate:self.process_UpLoad]; 19 //断点续传 20 [request setAllowResumeForFileDownloads:YES]; 21 [request startAsynchronous]; 22 } 23 24 - (IBAction)btn_Pause:(UIButton *)sender { 25 [request clearDelegatesAndCancel]; //暂停 26 } 27 @end
创建一个同步请求
这是ASIHTTPRequest最简单的一种使用模式,发送startSynchronous消息后即开始在同一线程中执行HTTP请求,线程将一直等待直到请求结束(请求成功或者失败)。通过检查error属性可以判断请求是否成功或者有错误发生。
要获取返回的文本信息,调用responseString方法。如果下载的是二进制文件,例如图片、MP3,则调用responseData方法,可以得到一个NSData对象。
- (IBAction)grabURL:(id)sender
{
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request startSynchronous];
NSError *error = [request error];
if (!error) {
NSString *response = [request responseString];
}
}
创建异步请求
一般情况下,应该优先使用异步请求代替同步请求,当在主线程中使用ASIHTTPRequest同步请求,应用程序的界面会锁定,无法进行任何操作,直到请求完成。
上例中的同步请求,如果换成异步方式来调用,请求是在后台线程中运行,当请求执行完后再通知调用的线程。这样不会导致主线程进行网络请求时,界面被锁定等情况。
- (IBAction)grabURLInBackground:(id)sender
{
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request startAsynchronous];
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
// 当以文本形式读取返回内容时用这个方法
NSString *responseString = [request responseString];
// 当以二进制形式读取返回内容时用这个方法
NSData *responseData = [request responseData];
}
- (void)requestFailed:(ASIHTTPRequest *)request
{
NSError *error = [request error];
}
a,与上面不同的地方是指定了一个 "delegate",并用startAsynchronous来启动网络请求。
b,在这里实现了两个delegate的方法,当数据请求成功时会调用requestFinished,请求失败时(如网络问题或服务器内部错误)会调用requestFailed。
ASIHTTPRequestDelegate回调方法 上面已经把下载请求与暂停请求实现,点击下载时,开始下载资源;当点暂停时,下载中断;当我们再点击下载按钮时,继续下载,在第二步的
[request setAllowResumeForFileDownloads:YES]设置是是否支持断点下载。下面要实现ASIHTTPRequestDelegate代理方法如下:
#pragma mark -
#pragma mark ASIHTTPRequestDelegate method
//ASIHTTPRequestDelegate,下载之前获取信息的方法,主要获取下载内容的大小,可以显示下载进度多少字节
- (void)request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders {
NSLog(@"didReceiveResponseHeaders-%@",[responseHeaders valueForKey:@"Content-Length"]);
NSLog(@"contentlength=%f",request.contentLength/1024.0/1024.0);
int bookid = [[request.userInfo objectForKey:@"bookID"] intValue];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
float tempConLen = [[userDefaults objectForKey:[NSString stringWithFormat:@"book_%d_contentLength",bookid]] floatValue];
NSLog(@"tempConLen=%f",tempConLen);
//如果没有保存,则持久化他的内容大小
if (tempConLen == 0 ) {//如果没有保存,则持久化他的内容大小
[userDefaults setObject:[NSNumber numberWithFloat:request.contentLength/1024.0/1024.0] forKey:[NSString stringWithFormat:@"book_%d_contentLength",bookid]];
}
}
//ASIHTTPRequestDelegate,下载完成时,执行的方法
- (void)requestFinished:(ASIHTTPRequest *)request {
int bookid = [[request.userInfo objectForKey:@"bookID"] intValue];
CustomCell *cell = (CustomCell *)[self.myTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:bookid inSection:0]];
cell.downloadCompleteStatus = YES;
cell.progressView.progress = 0.0;
}