ASIHTTPRequest 断点续传

最近学习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,不知怎么获取.


posted @ 2011-10-09 10:41  mew7wo  阅读(6120)  评论(0编辑  收藏  举报