(轉)ASIHTTPRequest 詳解, http 請求終結者

一月 8, 2012 • iPhone 開發 → asihttprequestObjective-Crequest php

ASIHTTPRequest是一款極其強勁的HTTP訪問開源項目。讓簡單的 API 完成複雜的功能,如:
異步請求,隊列請求,GZIP壓縮,緩存,斷點續傳,進度跟蹤,上傳文件,HTTP認證
在新的版本中,還加入了Objective-C閉包Block的支持,讓咱們的代碼更加輕簡靈活。 ios

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

發起一個同步請求

同步意爲着線程阻塞,在主線程中使用此方法會使應用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的子類。也就是說它能夠直接被放到」任務隊列」中,並被執行。上面的代碼隊了隊列的建立與添加操做外,其它代碼與上一例同樣。
請求隊列上下文

a,能夠設置一個上下文(userInfo)到request對象中,當請求響應完後能夠經過訪問request對象的userInfo獲取裏面的信息
b,爲每個請求實例設置不一樣的setDidFinishSelector / setDidFailSelector的回調方法
c,子類化ASIHTTPRequest,重寫requestFinished: 與 failWithProblem:方法 cookie

ASINetworkQueues, 它的delegate提供更爲豐富的功能

提供的更多的回調方法以下:
a,requestDidStartSelector,請求發起時會調此方法,你能夠在此方法中跟據業務選擇性的設置request對象的deleaget。
b,requestDidReceiveResponseHeadersSelector,當接受完響應的Header後設計此方法,這個對下載大數據的時候至關有用,你能夠在方法裏作更多業務上的處理。
c,requestDidFinishSelector,請求並響應成功完成時調用此方法
d,requestDidFailSelector,請求失敗
e,queueDidFinishSelector,整個隊列裏的全部請求都結束時調用此方法。 網絡

它是NSOperationQueues的擴展,小而強大。但也與它的父類略有區別。如,僅添加到隊列中其實並不能執行請求,只有調用[ queue g o]纔會執行;一個正在運行中的隊列,並不須要重複調用[ queue go ]。默認狀況下,隊列中的一個請求若是失敗,它會取消全部未完成的請求。能夠設置[ queue setShouldCancelAllRequestsOnFailure:NO ]來修 正。
取消異步請求

首先,同步請求是不能取消的。
其次,不論是隊列請求,仍是簡單的異步請求,所有調用[ request cancel ]來取消請求。 session

取消的請求默認都會按請求失敗處理,並調用請求失敗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之後支持大文件的斷點下載,只須要設置:

  1. [ request setAllowResumeForFileDownloads:YES ];   
  2. [ request setDownloadDestinationPath:downloadPath ];  

就能夠了。

ASIHTTPRequest會自動保存訪問過的URL信息,並備以後用。在如下幾個場景很是有用:
1,當沒有網絡鏈接的時候。
2,已下載的數據再次請求時,僅當它與本地版本不樣時才進行下載。

ASIDownloadCache 設置下載緩存

它對Get請求的響應數據進行緩存(被緩存的數據必需是成功的200請求):
[ASIHTTPRequest setDefaultCache:[ASIDownloadCache sharedCache]];
當設置緩存策略後,全部的請求都被自動的緩存起來。
另外,若是僅僅但願某次請求使用緩存操做,也能夠這樣使用:
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadCache:[ASIDownloadCache sharedCache]];

多種的緩存並存

僅僅須要建立不一樣的ASIDownloadCache,並設置緩存所使用的路徑,並設置到須要使用的request實例中:

  1. ASIDownloadCache *cache = [[[ASIDownloadCache alloc] init] autorelease];   
  2. [cache setStoragePath:@"/Users/ben/Documents/Cached-Downloads"];   
  3. [self setMyCache:cache];   
  4. ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];   
  5. [request setDownloadCache:[self myCache]];  
緩存策略

緩存策略是咱們控制緩存行爲的主要方式,如:何時進行緩存,緩存數據的利用方式。
如下是策略可選列表(可組合使用):

ASIUseDefaultCachePolicy 這是一個默認的緩存策略「ASIAskServerIfModifiedWhenStaleCachePolicy」,這個很明白,見名知意(它不能與其它策略組合使用)
ASIDoNotReadFromCacheCachePolicy 所讀數據不使用緩存
ASIDoNotWriteToCacheCachePolicy 不對緩存數據進行寫操做
ASIAskServerIfModifiedWhenStaleCachePolicy 默認緩存行爲,request會先判斷是否存在緩存數據。a, 若是沒有再進行網絡請求。 b,若是存在緩存數據,而且數據沒有過時,則使用緩存。c,若是存在緩存數據,但已通過期,request會先進行網絡請求,判斷服務器版本與本地版本是否同樣,若是同樣,則使用緩存。若是服務器有新版本,會進行網絡請求,並更新本地緩存
ASIAskServerIfModifiedCachePolicy 與默認緩存大體同樣,區別僅是每次請求都會 去服務器判斷是否有更新
ASIOnlyLoadIfNotCachedCachePolicy 若是有緩存在本地,無論其過時與否,總會拿來使用
ASIDontLoadCachePolicy 僅當有緩存的時候纔會被正確執行,若是沒有緩存,request將被取消(沒有錯誤信息)
ASIFallbackToCacheIfLoadFailsCachePolicy 這個選項常常被用來與其它選項組合使用。請求失敗時,若是有緩存當網絡則返回本地緩存信息(這個在處理異常時很是有用)
若是設置了「defaultCachePolicy」則全部的請求都會使用此緩存。
緩存存儲方式

你能夠設置緩存的數據須要保存多長時間,ASIHTTPRequest提供了兩種策略:
a,ASICacheForSessionDurationCacheStoragePolicy,默認策略,基於session的緩存數據存儲。當下次運行或[ASIHTTPRequest clearSession]時,緩存將失效。
b,ASICachePermanentlyCacheStoragePolicy,把緩存數據永久保存在本地,
如:

  1. ASIHTTPRequest *request = [ ASIHTTPRequest requestWithURL:url ];   
  2. [ request setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy ];  

另外,也可使用clearCachedResponsesForStoragePolicy來清空指定策略下的緩存數據。
緩存其它特性

設置是否按服務器在Header裏指定的是否可被緩存或過時策略進行緩存:

  1. [[ ASIDownloadCache sharedCache ] setShouldRespectCacheControlHeaders:NO ];  

設置request緩存的有效時間:
  1. [ request setSecondsToCache:60*60*24*30 ]; // 緩存30天  

能夠判斷數據是否從緩存讀取:
  1. [ request didUseCachedResponse ];  

設置緩存所使用的路徑:
  1. [ request setDownloadDestinationPath:[[ ASIDownloadCache sharedCache ] pathToStoreCachedResponseDataForRequest:request ]];  
實現自定義的緩存

只要簡單的實現ASICacheDelegate接口就能夠被用來使用。

使用代理請求

默認的狀況下,ASIHTTPRequest會使用被設置的默認代理。但你也能夠手動修改http代理:

  1. // Configure a proxy server manually   
  2. NSURL *url = [ NSURL URLWithString:@"http://allseeing-i.com/ignore" ];   
  3. ASIHTTPRequest *request = [ ASIHTTPRequest requestWithURL:url ];   
  4. [ request setProxyHost:@"192.168.0.1" ];   
  5. [ request setProxyPort:3128 ];   
  6.     
  7. // Alternatively, you can use a manually-specified Proxy Auto Config file (PAC)   
  8. // (It’s probably best if you use a local file)   
  9. [request setPACurl:[NSURL URLWithString:@"file:///Users/ben/Desktop/test.pac"]];  
ASIHTTPRequest, 請求的其它特性

iOS4中,當應用後臺運行時仍然請求數據:

  1. [ request setShouldContinueWhenAppEntersBackground:YES ];  

是否有網絡請求:
  1. [ ASIHTTPRequest isNetworkInUse ]  

是否顯示網絡請求信息在status bar上:
  1. [ ASIHTTPRequest setShouldUpdateNetworkActivityIndicator:NO ];  

設置請求超時時,設置重試的次數:
  1. [ request setNumberOfTimesToRetryOnTimeout:2 ];  

KeepAlive的支持:
  1. // Set the amount of time to hang on to a persistent connection before it should expire to 2 minutes   
  2. [ request setPersistentConnectionTimeoutSeconds:120 ];   
  3.     
  4. // Disable persistent connections entirely   
  5. [ request setShouldAttemptPersistentConnection:NO ];  

轉自:http://wiki.magiche.net/pages/viewpage.action?pageId=2064410

官方地址:http://allseeing-i.com/ASIHTTPRequest/

  • Previous
相關文章
相關標籤/搜索