ASIHTTPRequest用法

ASIHTTPRequest是一款極其強勁的HTTP訪問開源項目。讓簡單的API完成複雜的功能,

如:
異步請求,隊列請求,GZIP壓縮,緩存,斷點續傳,進度跟蹤,上傳文件,HTTP認證
在新的版本中,還加入了Objective-C閉包Block的支持,讓我們的代碼更加輕簡靈活。

下面就舉例說明它的API用法。

發起一個同步請求
同步意爲着線程阻塞,在主線程中使用此方法會使應用Hang住而不響應任何用戶事件。所以,在應用程序設計時,大多被用在專門的子線程增加用戶體驗,或用異步請求代替(下面會講到)。
複製代碼
  1. - (IBAction)grabURL:(id)sender
  2. {
  3.   NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
  4.   ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
  5.   [request startSynchronous];
  6.   NSError *error = [request error];
  7.   if (!error) {
  8.     NSString *response = [request responseString];
  9.   }
  10. }

a, 用requestWithURL快捷方法獲取ASIHTTPRequest的一個實例
b, startSynchronous 方法啓動同步訪問,
c, 由於是同步請求,沒有基於事件的回調方法,所以從request的error屬性獲取錯誤信息。
d, responseString,爲請求的返回NSString信息。

創建一個異步請求
異步請求的好處是不阻塞當前線程,但相對於同步請求略爲複雜,至少要添加兩個回調方法來獲取異步事件。
下面異步請求代碼完成上面同樣的一件事情:

複製代碼
  1. - (IBAction)grabURLInBackground:(id)sender
  2. {
  3.    NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
  4.    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
  5.    [request setDelegate:self];
  6.    [request startAsynchronous];
  7. }
  8.  
  9. - (void)requestFinished:(ASIHTTPRequest *)request
  10. {
  11.    // Use when fetching text data
  12.    NSString *responseString = [request responseString];
  13.  
  14.    // Use when fetching binary data
  15.    NSData *responseData = [request responseData];
  16. }
  17.  
  18. - (void)requestFailed:(ASIHTTPRequest *)request
  19. {
  20.    NSError *error = [request error];
  21. }


a,與上面不同的地方是指定了一個 "delegate",並用startAsynchronous來啓動網絡請求。
b,在這裏實現了兩個delegate的方法,當數據請求成功時會調用requestFinished,請求失敗時(如網絡問題服務器內部錯誤)會調用requestFailed。


隊列請求
提供了一個對異步請求更加精準豐富的控制。
如,可以設置在隊列中,同步請求的連接數。往隊列裏添加的請求實例數大於maxConcurrentOperationCount時,請求實例將被置爲等待,直到前面至少有一個請求完成並出列才被放到隊列裏執行。
也適用於當我們有多個請求需求按順序執行的時候(可能是業務上的需要,也可能是軟件上的調優),僅僅需要把maxConcurrentOperationCount設爲“1”。
複製代碼
  1. - (IBAction)grabURLInTheBackground:(id)sender
  2. {
  3.    if (![self queue]) {
  4.       [self setQueue:[[[NSOperationQueue alloc] init] autorelease]];
  5.    }
  6.  
  7.    NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
  8.    ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
  9.    [request setDelegate:self];
  10.    [request setDidFinishSelector:@selector(requestDone:)];
  11.    [request setDidFailSelector:@selector(requestWentWrong:)];
  12.    [[self queue] addOperation:request]; //queue is an NSOperationQueue
  13. }
  14.  
  15. - (void)requestDone:(ASIHTTPRequest *)request
  16. {
  17.    NSString *response = [request responseString];
  18. }
  19.  
  20. - (void)requestWentWrong:(ASIHTTPRequest *)request
  21. {
  22.    NSError *error = [request error];
  23. }


創建NSOperationQueue,這個Cocoa架構的執行任務(NSOperation)的任務隊列。我們通過ASIHTTPRequest.h的源碼可以看到,此類本身就是一個NSOperation的子類。也就是說它可以直接被放到"任務隊列"中,並被執行。上面的代碼隊了隊列的創建與添加操作外,其它代碼與上一例一樣。

隊列異步請求中中獲取或識別不同request小技巧
a,可以設置一個上下文(userInfo)到request對象中,當請求響應完後可以通過訪問request對象的userInfo獲取裏面的信息
b,爲每一個請求實例設置不同的setDidFinishSelector / setDidFailSelector的回調方法
c,子類化ASIHTTPRequest,重寫requestFinished: 與 failWithProblem:方法

ASINetworkQueues, 它的delegate提供更爲豐富的功能
提供的更多的回調方法如下:
a,requestDidStartSelector,請求發起時會調此方法,你可以在此方法中跟據業務選擇性的設置request對象的deleaget。
b,requestDidReceiveResponseHeadersSelector,當接受完響應的Header後設計此方法,這個對下載大數據的時候相當有用,你可以在方法裏做更多業務上的處理。
c,requestDidFinishSelector,請求並響應成功完成時調用此方法
d,requestDidFailSelector,請求失敗
e,queueDidFinishSelector,整個隊列裏的所有請求都結束時調用此方法。
  
它是NSOperationQueues的擴展,小而強大。但也與它的父類略有區別。如,僅添加到隊列中其實並不能執行請求,只有調用[  queue g o ]纔會執行;一個正在運行中的隊列,並不需要重複調用[  queue go  ]。

引用
text\">
默認情況下,隊列中的一個請求如果失敗,它會取消所有未完成的請求。可以設置[  queue setShouldCancelAllRequestsOnFailure:NO  ]來修 正。
 



取消異步請求
首先,同步請求是不能取消的。
其次,不管是隊列請求,還是簡單的異步請求,全部調用[ request cancel ]來取消請求。


引用
取消的請求默認都會按請求失敗處理,並調用請求失敗delegate。
如果不想調用delegate方法,則設置:[ request clearDelegatesAndCancel];


隊列請求中需要注意的是,如果你取消了一個請求,隊列會自動取消其它所有請求。
如果只想取消一個請求,可以設置隊列:[ queue setShouldCancelAllRequestsOnFailure:NO ];
如果想明確取消所有請求:[ queue cancelAllOperations ];

安全的內存回收建議
request並沒有retain你的delegate,所以在沒有請求完的時候釋放了此delegate,需要在dealloc方法裏先取消所有請求,再釋放請求實例,如:
複製代碼
  1. - (void)dealloc
  2. {
  3.    [request clearDelegatesAndCancel];
  4.    [request release];
  5.    ...
  6.    [super dealloc];
  7. }


向服務器端上傳數據
ASIFormDataRequest ,模擬 Form表單提交,其提交格式與 Header會自動識別。
沒有文件:application/x-www-form-urlencoded
有文件:multipart/form-data

複製代碼
  1. ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
  2. [request setPostValue:@"Ben" forKey:@"first_name"];
  3. [request setPostValue:@"Copsey" forKey:@"last_name"];
  4. [request setFile:@"/Users/ben/Desktop/ben.jpg" forKey:@"photo"];
  5. [request addData:imageData withFileName:@"george.jpg" andContentType:@"image/jpeg" forKey:@"photos"];


如果要發送自定義數據:
複製代碼
  1. ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
  2. [request appendPostData:[@"This is my data" dataUsingEncoding:NSUTF8StringEncoding]];
  3. // Default becomes POST when you use appendPostData: / appendPostDataFromFile: / setPostBody:
  4. [request setRequestMethod:@"PUT"];


下載文件
通過設置request的setDownloadDestinationPath,可以設置下載文件用的下載目標目錄。
首先,下載過程文件會保存在temporaryFileDownloadPath目錄下。如果下載完成會做以下事情:
1,如果數據是壓縮的,進行解壓,並把文件放在downloadDestinationPath目錄中,臨時文件被刪除
2,如果下載失敗,臨時文件被直接移到downloadDestinationPath目錄,並替換同名文件。

如果你想獲取下載中的所有數據,可以實現delegate中的request:didReceiveData:方法。但如果你實現了這個方法,request在下載完後,request並不把文件放在downloadDestinationPath中,需要手工處理。

獲取響應信息
信息:status , header, responseEncoding

複製代碼
  1. [request responseStatusCode];
  2. [[request responseHeaders] objectForKey:@"X-Powered-By"];
  3. [request responseEncoding];



獲取請求進度
有兩個回調方法可以獲取請求進度,
1,downloadProgressDelegate,可以獲取下載進度
2,uploadProgressDelegate,可以獲取上傳進度

cookie的支持
如果Cookie存在的話,會把這些信息放在NSHTTPCookieStorage容器中共享,並供下次使用。
你可以用[ ASIHTTPRequest setSessionCookies:nil ] ; 清空所有Cookies。
當然,你也可以取消默認的Cookie策略,而使自定義的Cookie:
複製代碼
  1. //Create a cookie
  2. NSDictionary *properties = [[[NSMutableDictionary alloc] init] autorelease];
  3. [properties setValue:[@"Test Value" encodedCookieValue] forKey:NSHTTPCookieValue];
  4. [properties setValue:@"ASIHTTPRequestTestCookie" forKey:NSHTTPCookieName];
  5. [properties setValue:@".allseeing-i.com" forKey:NSHTTPCookieDomain];
  6. [properties setValue:[NSDate dateWithTimeIntervalSinceNow:60*60] forKey:NSHTTPCookieExpires];
  7. [properties setValue:@"/asi-http-request/tests" forKey:NSHTTPCookiePath];
  8. NSHTTPCookie *cookie = [[[NSHTTPCookie alloc] initWithProperties:properties] autorelease];
  9.  
  10. //This url will return the value of the 'ASIHTTPRequestTestCookie' cookie
  11. url = [NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/read_cookie"];
  12. request = [ASIHTTPRequest requestWithURL:url];
  13. [request setUseCookiePersistence:NO];
  14. [request setRequestCookies:[NSMutableArray arrayWithObject:cookie]];
  15. [request startSynchronous];
  16.  
  17. //Should be: I have 'Test Value' as the value of 'ASIHTTPRequestTestCookie'
  18. NSLog(@"%@",[request responseString]);



大文件斷點續傳
0.94以後支持大文件的斷點下載,只需要設置:
  [ request setAllowResumeForFileDownloads:YES ];
  [ request setDownloadDestinationPath:downloadPath ];
就可以了。

版權歸旺財勇士所有~轉載需聲名~

首發自:http://wiki.magiche.net/pages/viewpage.action?pageId=2064410
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章