ASIHttpRequest:建立佇列、下載請求、斷點續傳、解壓縮

weixin_34119545發表於2013-07-03

ps:本文轉載自網路:http://ryan.easymorse.com/?p=12 感謝作者 

工程完整程式碼下載地址:RequestTestDownload1

可完成:

  • 下載指定連結的zip壓縮檔案
  • 存放在Documents目錄下
  • 支援斷點續傳
  • 顯示下載進度
  • 解壓到指定目錄

——————————————————————————————————————————————

首先,要想在ios專案中使用ASIHttpRequest,必須新增下列框架和類庫:

  • ASIHttpRequest   【庫的下載地址】
  • CFNetwork.framework
  • SystemConfiguration.framework
  • MobileCoreServices.framework
  • CoreGraphics.framework
  • libz.dylib【這個可能會有變動,有人在ios5.0上執行不了,在專案中新增{libz.1.2.5.dylib}】

——————————————————————————————————————————————

建立一個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;

//設定下載路徑

 [request setDownloadDestinationPath:downloadPath];

//設定快取路徑

[request setTemporaryFileDownloadPath:tempPath];

//設定支援斷點續傳

[request setAllowResumeForFileDownloads: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 = [[queue operations] objectAtIndex:0];

    //取消請求

    [request clearDelegatesAndCancel];

}

你可能注意到了一個問題,因為我們的佇列裡只有一個請求,所以很容易獲取。如果請求多了,我們應該怎麼區分佇列裡的請求呢?有兩個方法:

  1. 設定request的tag屬性,就像UIView的tag一樣方便,但是擴充套件性不強;
  2. 設定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 = [unzip UnzipFileTo:unzipPathoverWrite:YES];

        if (result) {

            NSLog(@”解壓成功!”);

        }

        [unzip UnzipCloseFile];

    }

    [unzip release];

}

OK!解壓成功,現在應該可以看到解壓後的檔案了:

參考:

相關文章