最近学习ASIHTTPRequest如何使用,所以利用ASIHTTPRequest自身的功能,写了个可断点下载的小demo
我利用tableview作为下载列表,所有自己custom了一个cell,用来控制下载
enum DownloadStatus { DownloadNotStart = 0, Downloading, DownloadPause, DownloadFinish};@interface DownloadFileListTableViewCell : UITableViewCell <ASIHTTPRequestDelegate, ASIProgressDelegate>{ UIProgressView *_progressView; UIButton *_controlButton; UILabel *_sizeTip; ASIHTTPRequest *_asiRequest; NSURL *_oriURL; enum DownloadStatus _downloadStatus; NSString *_saveFilePath; NSString *_tmpFilePath; long long _curSize; long long _totalSize;}
最新的 ASIHTTPRequest 自己有一个支持断点下载的方法,
[_asiRequest setTemporaryFileDownloadPath:_tmpFilePath]; [_asiRequest setAllowResumeForFileDownloads:YES];
只要设置了这两个,就可以实现断点下载
下面是我自己实现的几个控制下载的方法
- (void)startDownload{ _curSize = 0; _totalSize = 0; _asiRequest = [[ASIHTTPRequest alloc] initWithURL:_oriURL]; [_asiRequest setDelegate:self]; [_asiRequest setDownloadProgressDelegate:self]; [_asiRequest setShowAccurateProgress:YES]; [_asiRequest setDownloadDestinationPath:_saveFilePath]; [_asiRequest setTemporaryFileDownloadPath:_tmpFilePath]; [_asiRequest setAllowResumeForFileDownloads:YES]; _downloadStatus = Downloading; [_controlButton setTitle:@"Pause" forState:UIControlStateNormal]; [_asiRequest startAsynchronous];}- (void)pauseDownload{ [_asiRequest clearDelegatesAndCancel]; [_asiRequest release], _asiRequest = nil; _downloadStatus = DownloadPause; [_controlButton setTitle:@"Resume" forState:UIControlStateNormal];}- (void)resumeDownload{ _curSize = 0; _asiRequest = [[ASIHTTPRequest alloc] initWithURL:_oriURL]; [_asiRequest setDelegate:self]; [_asiRequest setDownloadProgressDelegate:self]; [_asiRequest setShowAccurateProgress:YES]; [_asiRequest setDownloadDestinationPath:_saveFilePath]; [_asiRequest setTemporaryFileDownloadPath:_tmpFilePath]; [_asiRequest setAllowResumeForFileDownloads:YES]; _downloadStatus = Downloading; [_controlButton setTitle:@"Pause" forState:UIControlStateNormal]; [_asiRequest startAsynchronous];}- (void)finishDownload{ [_controlButton setTitle:@"Finish" forState:UIControlStateNormal]; _downloadStatus = DownloadFinish; NSLog(@"success Finish Download");}
因为要利用progressview手动记录下载情况,所以,继承了ASIProgressDelegate,并实现了
- (void)request:(ASIHTTPRequest *)request didReceiveBytes:(long long)bytes{ // when resume download, the bytes is the size of the file which had down _curSize += bytes; float value = (_curSize*1.0)/(_totalSize*1.0); [_progressView setProgress:value]; float tmp = 1024*1024.0; NSString *tip = [NSString stringWithFormat:@"%.1lf/%.1lfM", _curSize/tmp, _totalSize/tmp]; [_sizeTip setText:tip];}
这样,就可以随时记录下载情况了.
写这个demo的过程中,还遇到了url redirect的问题,ASIHTTPRequest本身是可以auto redirect的,但是不知什么原因,我这里并没有auto redirect,所以,我自己手动控制它redirect(实现ASIHTTPRequestDelegate的requestFailed方法)
- (void)requestFailed:(ASIHTTPRequest *)request{ NSError *error = [request error]; [_controlButton setTitle:@"Fail" forState:UIControlStateNormal]; NSLog(@"Failed error : %@", [error localizedDescription]); NSDictionary *resp = [request responseHeaders]; NSString *redirectURL = [resp valueForKey:@"Location"]; if([request responseStatusCode] == 302 && redirectURL){ [self redirectToDest:redirectURL]; }}
当然,status code = 301的时候也需要redirect,我这里就没加上了.
到这里,我还遇到个问题就是,每次下载都定死了文件名,当下载多个文件时,会导致文件重写,所以,要时不同文件不重复,且能很好的辨认,最后的办法就是能从头部中获取服务端返回的文件名,并以此命名.但是,在ASIHTTPRequet的responseHeader中却找不到这个值.经google后得知,需要自己解析header 的 Content-Disposition.所以,我想获取ASIHTTPRequest刚获取的header,不知怎么获取.
来源:https://www.cnblogs.com/mew7wo/archive/2011/10/09/2203381.html