ASIHttpRequest 队列下载/暂停
我的第一篇博客,刚好是今天有个朋友在群里(Mark_@_iOS:241465868)问大家队列下载如何实现,可能这个问题比较基础吧,大牛们不怎么想回答了,然后刚好我有空,就一起研究了一下,研究出来的结果也就晒出来当做我的第一篇博客了。 OK,废话到此为止,开始。
先贴上代码
- (void)viewDidLoad
{
[super viewDidLoad];
//创建路径、下载地址、缓存地址
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
urlList=@[[NSURL URLWithString:@"http://data8.5sing.com/T1GDbLB4ZT1R47IVrK.mp3"],[NSURL URLWithString:@"http://b.hiphotos.baidu.com/image/pic/item/7acb0a46f21fbe093af8049169600c338644ad95.jpg"]];
requestList = [NSMutableArray array];
downPathList = @[[path stringByAppendingPathComponent:@"test1.jpg"],[path stringByAppendingPathComponent:@"test2.jpg"]];
tempPathList = @[[path stringByAppendingPathComponent:@"temp1.tmp"],[path stringByAppendingPathComponent:@"temp2.tmp"]];
queue = [[ASINetworkQueue alloc] init];
mark=0;
//设置支持较高精度的进度追踪
[queue setShowAccurateProgress:YES];
//启动
//启动后,添加到队列的请求会自动执行
[queue go];
}
- (IBAction)startDownload
{
//创建ASIHttpRequest并添加到队列中
for (int i=0; i<[urlList count]; i++) {
[self addRequestWithUrl:[urlList objectAtIndex:i] Patch:[tempPathList objectAtIndex:i] downloadPath:[downPathList objectAtIndex:i]];
}
}
- (void)addRequestWithUrl:(NSURL *)url Patch:(NSString *)tempPath downloadPath:(NSString *)downloadPath
{
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[requestList addObject:request];
//设置代理,别忘了在头文件里添加ASIHTTPRequestDelegate协议
request.delegate = self;
//设置下载路径
[request setDownloadDestinationPath:downloadPath];
//设置缓存路径
[request setTemporaryFileDownloadPath:tempPath];
//设置支持断点续传
[request setAllowResumeForFileDownloads:YES];
//下载进度代理可以直接用UIProgressView对象,它会自动更新,如果你想做更多的处理
//就必须用我们自定义的类,只要我们的类里实现了setPorgress:方法
request.downloadProgressDelegate = self;
//将请求添加到之前创建的队列里,这时请求已经开始执行了
//队列会retain添加进去的请求
[queue addOperation:request];
}
//请求收到响应的头部,主要包括文件大小信息,下面会用到
//对头部信息的处理
- (void)request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders
{
NSLog(@"%@",responseHeaders);
}
//最后,便是暂停
- (IBAction)pauseDownload
{
//operations方法返回队列里的所有请求,但我们只有一个请求
// ASIHTTPRequest *request = [[queue operations] objectAtIndex:0];
NSArray *tempRequestList=[queue operations];
for (ASIHTTPRequest *request in tempRequestList) {
//取消请求
[request clearDelegatesAndCancel];
}
}
你可能注意到了一个问题,因为我们的队列里只有一个请求,所以很容易获取。如果请求多了,我们应该怎么区分队列里的请求呢?有两个方法:
设置request的tag属性,就像UIView的tag一样方便,但是扩展性不强;
设置request的userInfo属性,它是个NSDictionary对象,下面不用我说了吧。
还有一件事,我们使用了clearDelegatesAndCancel方法来取消请求,我们本可以用cancel方法来达到同样的目的,但后者会使request触发代理方法requestFailed:,而前者会首先重置request的所有代理然后执行cancel方法,所以不会触发代理方法。这里还要说一下,如果你的request代理在request被取消之前释放,那么代理方法被触发的时候就会crash!如果必须释放你的代理,请确定执行了clearDelegatesAndCancel方法!
还应该注意,这里说是暂停,其实request已经完全被取消了!下面说说断点续传是怎么回事。
其实,断点续传的功能我们在上面的代码里已经实现了。不信?
因为我们之前开启了断点续传,并且设置了缓存路径,所以request取消时就会在缓存文件里打断点,当我们在次执行上面的startDownload方法时,缓存路径还是之前的缓存路径,request会自动从缓存文件中的断点后开始下载,头部中的文件大小值也是从断点之后开始算的。神奇吧,ASIHTTPRequest已经为你打点好了一切。
继续,当请求完成时,也就是我们的文件已经下载好了的时候,下载好的文件会在我们之前指定的下载路径下生成,同时缓存文件会被删除,具体谁先谁后目前还没有弄清楚。