創建隊列、下載請求、斷點續傳、解壓縮
剛剛開始學習ASIHttpRequest,今天通過自己寫的一個小demo分享一下學習心得。
首先,要想在ios項目中使用ASIHttpRequest,必須添加下列框架和類庫:
- ASIHttpRequest
- CFNetwork.framework
- SystemConfiguration.framework
- MobileCoreServices.framework
- CoreGraphics.framework
- libz.dylib
下面是我們今天要完成的任務:
- 下載指定鏈接的zip壓縮文件
- 存放在Documents目錄下
- 支持斷點續傳
- 顯示下載進度
- 解壓到指定目錄
那就開始吧,首先我們要創建一個ASINetworkQueue全局隊列,隊列裏可以添加請求,雖然今天只會用到一個請求,但我們遲早會用到隊列,不妨現在就開始創建:
- (void)viewDidLoad
{
queue = [[ASINetworkQueue alloc] init];
//設置支持較高精度的進度追蹤
[queue setShowAccurateProgress:YES];
//啓動
//啓動後,添加到隊列的請求會自動執行
[queue go];
}
緊接着創建我們的下載請求:
- (IBAction)startDownload
{
//Documents路徑
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
//下載路徑
downloadPath = [[path stringByAppendingPathComponent:@"book.zip"] retain];
//要支持斷點續傳,緩存路徑是不能少的。
NSString *tempPath = [path stringByAppendingPathComponent:@"book.temp"];
//下載鏈接
NSURL *url = [NSURL URLWithString:@"http://cnread.net/cnread1/lszl/s/simaguang/zztj/zztj.zip"];
//創建請求
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
//設置代理,別忘了在頭文件裏添加ASIHTTPRequestDelegate協議
request.delegate = self;
//設置下載路徑
[requestsetDownloadDestinationPath:downloadPath];
//設置緩存路徑
[requestsetTemporaryFileDownloadPath:tempPath];
//設置支持斷點續傳
[requestsetAllowResumeForFileDownloads:YES];
//下載進度代理可以直接用UIProgressView對象,它會自動更新,如果你想做更多的處理
//就必須用我們自定義的類,只要我們的類裏實現了setPorgress:方法
request.downloadProgressDelegate = self;
//將請求添加到之前創建的隊列裏,這時請求已經開始執行了
//隊列會retain添加進去的請求
[queue addOperation:request];
}
由於我們沒有設置代理方法,request會執行下列默認代理方法:
//請求開始
- (void)requestStarted:(ASIHTTPRequest *)request;
//請求收到響應的頭部,主要包括文件大小信息,下面會用到
- (void)request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders;
//請求將被重定向
- (void)request:(ASIHTTPRequest *)request willRedirectToURL:(NSURL *)newURL;
//請求完成
- (void)requestFinished:(ASIHTTPRequest *)request;
//請求失敗
- (void)requestFailed:(ASIHTTPRequest *)request;
//請求已被重定向
- (void)requestRedirected:(ASIHTTPRequest *)request;
下面是我們對頭部信息的處理
- (void)request:(ASIHTTPRequest *)request didReceiveResponseHeaders:(NSDictionary *)responseHeaders
{
NSLog(@”%@”,responseHeaders);
if (fileLength == 0) {
fileLength = request.contentLength/1024.0/1024.0;
totalPro.text = [NSString stringWithFormat:@"%.2fM",fileLength];
}
}
這是打印的結果:
{
“Accept-Ranges” = bytes;
“Content-Length” = 4380152;
“Content-Type” = “application/x-zip-compressed”;
Date = “Fri, 25 Nov 2011 11:43:20 GMT”;
Etag = “\”16d81c5cba6c71:78c\”";
“Last-Modified” = “Sun, 03 Jun 2007 18:16:52 GMT”;
Server = “Microsoft-IIS/6.0″;
“X-Powered-By” = “ASP.NET”;
}
我們可以從中看到文件大小等一些請求信息,這時request自己也知道了文件大小,所以我們直接使用request的contentLength屬性,放心,大小是一樣的!
經過測試,緩存文件是在收到頭部後創建的。
這是處理進度的方法(request會自動調用該方法):
- (void)setProgress:(float)newProgress
{
progressView.progress = newProgress;
currentPro.text = [NSString stringWithFormat:@"%.2fM",fileLength*newProgress];
}
這樣我們就可以看到進度了:
界面比較簡陋,見笑了。。。
下面是我們的暫停方法
- (IBAction)pauseDownload
{
//operations方法返回隊列裏的所有請求,但我們只有一個請求
ASIHTTPRequest *request = [[queueoperations] objectAtIndex:0];
//取消請求
[request clearDelegatesAndCancel];
}
你可能注意到了一個問題,因爲我們的隊列裏只有一個請求,所以很容易獲取。如果請求多了,我們應該怎麼區分隊列裏的請求呢?有兩個方法:
- 設置request的tag屬性,就像UIView的tag一樣方便,但是擴展性不強;
- 設置request的userInfo屬性,它是個NSDictionary對象,下面不用我說了吧。
還有一件事,我們使用了clearDelegatesAndCancel方法來取消請求,我們本可以用cancel方法來達到同樣的目的,但後者會使request觸發代理方法requestFailed:,而前者會首先重置request的所有代理然後執行cancel方法,所以不會觸發代理方法。
這裏還要說一下,如果你的request代理在request被取消之前釋放,那麼代理方法被觸發的時候就會crash!如果必須釋放你的代理,請確定執行了clearDelegatesAndCancel方法!
還應該注意,這裏說是暫停,其實request已經完全被取消了!下面說說斷點續傳是怎麼回事。
其實,斷點續傳的功能我們在上面的代碼裏已經實現了。不信?
因爲我們之前開啓了斷點續傳,並且設置了緩存路徑,所以request取消時就會在緩存文件裏打斷點,當我們在次執行上面的startDownload方法時,緩存路徑還是之前的緩存路徑,request會自動從緩存文件中的斷點後開始下載,頭部中的文件大小值也是從斷點之後開始算的。神奇吧,ASIHTTPRequest已經爲你打點好了一切。
繼續,當請求完成時,也就是我們的文件已經下載好了的時候,下載好的文件會在我們之前指定的下載路徑下生成,同時緩存文件會被刪除,具體誰先誰後目前還沒有弄清楚。
現在我們的壓縮文件已經下載好了,可怎麼打開呢,雙擊?NO,繼續:
爲了使用解壓縮,我引用了第三方類庫:
解壓縮的代碼如下:
- (IBAction)unzipFile
{
//初始化Documents路徑
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
//創建文件夾路徑,這將是解壓的目的路徑
unzipPath = [[path stringByAppendingPathComponent:@"bookUnzip"] retain];
//創建解壓器
ZipArchive *unzip = [[ZipArchive alloc] init];
if ([unzip UnzipOpenFile:downloadPath]) {
//解壓
BOOL result = [unzipUnzipFileTo:unzipPath overWrite:YES];
if (result) {
NSLog(@”解壓成功!”);
}
[unzip UnzipCloseFile];
}
[unzip release];
}
OK!解壓成功,現在應該可以看到解壓後的文件了:
大功告成!!!
現在回頭看看一開始的任務:
- 下載指定鏈接的zip壓縮文件
- 存放在Documents目錄下
- 支持斷點續傳
- 顯示下載進度
- 解壓到指定目錄
沒錯都完成了!下面是我的項目文件,裏面添加了刪除和閱讀功能:
參考:
- http://www.dreamingwish.com/dream-2011/powerful-asihttprequest-library-two.html
- http://www.cocoachina.com/bbs/read.php?tid=61709&keyword=ASIHttpRequest
第一次這麼正經的寫博客,很不習慣,以後儘量多寫,謝謝觀看!!!