ASIHTTPRequest系列(一):同步和異步請求
ASIHTTPRequest提供如下功能:
1、提交數據到web服務器或者從web服務器獲得數據;
2、下載數據到內存或磁盤;
3、采用html input相同的機制上傳文件;
4、斷點續傳;
5、簡單存取HTTP頭;
6、上傳/下載進度顯示;
7、支持Cookie;
8、后臺運行(iOS4.0以上支持);
9、對于請求和響應的GZIP支持;
10、支持客戶端證書;
11、支持同步/異步請求;
......
關于它的介紹網上已經有很多了,該項目有很詳細的指南文檔:How to use ASIHTTPRequest,也有網友翻譯成中文了。本文沒有完全照搬官方文檔的內容,而是著重介紹了幾個常見的應用,并涵蓋了一些自己的理解和實際應用經驗,包括:
安裝、簡單異步/同步請求、隊列請求、上傳、下載及 Cookies
注意,雖然這些技術在本文中是分開講述的,但在實際工作中,往往是多種技術結合應用的。
此外,Http請求往往伴隨著XML技術的應用,實際上ASIHTTPRequest是可以和SAX異步解析結合應用的,這部分內容請參考《ASIHTTPRequest和libxml結合,實現邊請求邊解析》。
項目下載地址: http://github.com/pokeb/asi-http-request/tarball/master
解壓縮并打開文件夾,其中包括:
1、一個iPhone Xcode項目(源文件)
2、一個Mac Xcode項目(源文件)
3、一個iPhone下使用的Sample Code(源文件)
4、一個Mac下使用的Sample Code(源文件)
5、一個Readme.texttile,關于該項目的介紹
其實所有的內容都在其中了,如果你是初學者,不知到怎么下手,可以看 http://allseeing-i.com/ASIHTTPRequest/How-to-use這里有一份詳細的入門指南。
現在,我們要做的就是,在自己的項目中使用它。
一、在項目中使用ASIHTTPRequest
1、拷貝源文件到項目中
ASIHTTPRequest是一個開源項目,要使用它,直接拷貝項目源文件到你的項目中,包括下列文件(即Classes下所有文件和External/Reachability下所有文件):
ASIHTTPRequestConfig.h
ASIHTTPRequestDelegate.h
ASIProgressDelegate.h
ASICacheDelegate.h
ASIHTTPRequest.h
ASIHTTPRequest.m
ASIDataCompressor.h
ASIDataCompressor.m
ASIDataDecompressor.h
ASIDataDecompressor.m
ASIFormDataRequest.h
ASIInputStream.h
ASIInputStream.m
ASIFormDataRequest.m
ASINetworkQueue.h
ASINetworkQueue.m
ASIDownloadCache.h
ASIDownloadCache.m
對于 iPhone,還要拷貝下列文件:
ASIAuthenticationDialog.h
ASIAuthenticationDialog.m
Reachability.h (External/Reachability目錄)
Reachability.m(External/Reachability目錄)
ASIHTTPRequest依賴于以下5個框架或庫:
CFNetwork、SystemConfiguration、MobileCoreServices、CoreGraphics和libz1.2.3。
依次將上述庫和框架添加到target的Linked Libraries中。
二、簡單的同步請求示例
新建iOS項目,加入必需的源文件和Linked Libraries。往MainWindow.xib中添加一個UIButton,添加相應的outlet與action。編寫按鈕的Touch up inside代碼,并連接到UIButton:
- (IBAction)goURL { NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"]; // 構造ASIHTTPRequest對象 ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; // 開始同步請求 [request startSynchronous]; NSError *erro = [request error]; assert(!erro); // 如果請求成功,返回Response NSString *response = [request responseString]; NSLog(@"%@", response); }
別忘了在適當的地方導入ASIHTTPRequest:#import "ASIHTTPRequest.h"分別保存IB和Xcode中所做的更改,?+B編譯。
三、簡單的異步請求示例
將上述代碼修改為:
- (IBAction)goURL { NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"]; ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; // 設定委托,委托自己實現異步請求方法 [request setDelegate: self]; // 開始異步請求 [request startAsynchronous]; }并 實現一系列委托方法:(別忘了在.h中添加import頭文件以及delegate)
- (IBAction)goURL { NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"]; __block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; // ASIHTTPRequest支持iOS4.0的塊語法,可以把委托方法定義到塊中 [request setCompletionBlock:^{ // 請求響應結束,返回response NSString *response = [request responseString]; // 對于2進制數據,使用:NSData *response = [request responseData]; NSLog(@"%@", response); }]; [request setFailedBlock:^{ // 請求失敗,獲取error NSError *error = [request error]; NSLog(@"%@", [error userInfo]); }]; [request startAsynchronous]; }
但此時出現了郁悶的一幕,代碼塊中的request對象出現警告信息:Capturing 'request' strongly in this block is likely to lead to a retain cycle。看到這個我就知道麻煩了,然后我查了一些資料,但沒有很好的解決這個問題,大家可以參考一下這里 Block的Retain Cycle的解決方法 。要是有誰知道麻煩說一下,大家相互學習。