ASIHTTPRequest是一款極其強勁的HTTP訪問開源項目哟玷。讓簡單的API完成復雜的功能,
如:
異步請求一也,隊列請求巢寡,GZIP壓縮,緩存椰苟,斷點續(xù)傳抑月,進度跟蹤,上傳文件舆蝴,HTTP認證
在新的版本中谦絮,還加入了Objective-C閉包Block的支持题诵,讓我們的代碼更加輕簡靈活。
下面就舉例說明它的API用法层皱。
發(fā)起一個同步請求
同步意為著線程阻塞性锭,在主線程中使用此方法會使應用Hang住而不響應任何用戶事件。所以奶甘,在應用程序設計時篷店,大多被用在專門的子線程增加用戶體驗,或用異步請求代替(下面會講到)臭家。
- (IBAction)grabURL:(id)sender
{
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request startSynchronous];
NSError *error = [request error];
if (!error) {
NSString *response = [request responseString];
}
}
- 用requestWithURL快捷方法獲取ASIHTTPRequest的一個實例
- startSynchronous 方法啟動同步訪問疲陕,
- 由于是同步請求,沒有基于事件的回調(diào)方法钉赁,所以從request的error屬性獲取錯誤信息蹄殃。
- responseString,為請求的返回NSString信息你踩。
創(chuàng)建一個異步請求
異步請求的好處是不阻塞當前線程诅岩,但相對于同步請求略為復雜,至少要添加兩個回調(diào)方法來獲取異步事件带膜。
下面異步請求代碼完成上面同樣的一件事情:
- (IBAction)grabURLInBackground:(id)sender
{
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request startAsynchronous];
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
// Use when fetching text data
NSString *responseString = [request responseString];
// Use when fetching binary data
NSData *responseData = [request responseData];
}
- (void)requestFailed:(ASIHTTPRequest *)request
{
NSError *error = [request error];
}
- 與上面不同的地方是指定了一個 "delegate"吩谦,并用startAsynchronous來啟動網(wǎng)絡請求。
- 在這里實現(xiàn)了兩個delegate的方法膝藕,當數(shù)據(jù)請求成功時會調(diào)用requestFinished,請求失敗時(如網(wǎng)絡問題或服務器內(nèi)部錯誤)會調(diào)用requestFailed滑废。
隊列請求
提供了一個對異步請求更加精準豐富的控制辛馆。
如昙篙,可以設置在隊列中,同步請求的連接數(shù)。往隊列里添加的請求實例數(shù)大于maxConcurrentOperationCount時硕蛹,請求實例將被置為等待法焰,直到前面至少有一個請求完成并出列才被放到隊列里執(zhí)行乙濒。
也適用于當我們有多個請求需求按順序執(zhí)行的時候(可能是業(yè)務上的需要傻丝,也可能是軟件上的調(diào)優(yōu))甘有,僅僅需要把maxConcurrentOperationCount設為“1”。
- (IBAction)grabURLInTheBackground:(id)sender
{
if (![self queue]) {
[self setQueue:[[[NSOperationQueue alloc] init] autorelease]];
}
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request setDidFinishSelector:@selector(requestDone:)];
[request setDidFailSelector:@selector(requestWentWrong:)];
[[self queue] addOperation:request]; //queue is an NSOperationQueue
}
- (void)requestDone:(ASIHTTPRequest *)request
{
NSString *response = [request responseString];
}
- (void)requestWentWrong:(ASIHTTPRequest *)request
{
NSError *error = [request error];
}
創(chuàng)建NSOperationQueue,這個Cocoa架構的執(zhí)行任務(NSOperation)的任務隊列。我們通過ASIHTTPRequest.h的源碼可以看到随橘,此類本身就是一個NSOperation的子類。也就是說它可以直接被放到"任務隊列"中牙言,并被執(zhí)行卑硫。上面的代碼隊了隊列的創(chuàng)建與添加操作外,其它代碼與上一例一樣桐款。
請求隊列上下文
- 可以設置一個上下文(userInfo)到request對象中魔眨,當請求響應完后可以通過訪問request對象的userInfo獲取里面的信息
- 為每一個請求實例設置不同的setDidFinishSelector / setDidFailSelector的回調(diào)方法
- 子類化ASIHTTPRequest媳维,重寫requestFinished: 與 failWithProblem:方法
ASINetworkQueues, 它的delegate提供更為豐富的功能
提供的更多的回調(diào)方法如下:
- requestDidStartSelector,請求發(fā)起時會調(diào)此方法遏暴,你可以在此方法中跟據(jù)業(yè)務選擇性的設置request對象的deleaget侄刽。
- requestDidReceiveResponseHeadersSelector,當接受完響應的Header后設計此方法朋凉,這個對下載大數(shù)據(jù)的時候相當有用州丹,你可以在方法里做更多業(yè)務上的處理。
- requestDidFinishSelector杂彭,請求并響應成功完成時調(diào)用此方法
- requestDidFailSelector墓毒,請求失敗
- queueDidFinishSelector,整個隊列里的所有請求都結束時調(diào)用此方法亲怠。
它是NSOperationQueues的擴展所计,小而強大。但也與它的父類略有區(qū)別团秽。如主胧,僅添加到隊列中其實并不能執(zhí)行請求,只有調(diào)用[ queue g o]才會執(zhí)行习勤;一個正在運行中的隊列踪栋,并不需要重復調(diào)用[ queue go ]。
默認情況下图毕,隊列中的一個請求如果失敗夷都,它會取消所有未完成的請求∮璨可以設置[ queue setShouldCancelAllRequestsOnFailure:NO ]來修正囤官。
取消異步請求
首先厢破,同步請求是不能取消的。
其次治拿,不管是隊列請求,還是簡單的異步請求笆焰,全部調(diào)用[ request cancel]來取消請求劫谅。
取消的請求默認都會按請求失敗處理,并調(diào)用請求失敗delegate嚷掠。
如果不想調(diào)用delegate方法捏检,則設置:[ request clearDelegatesAndCancel];
隊列請求中需要注意的是,如果你取消了一個請求不皆,隊列會自動取消其它所有請求贯城。
如果只想取消一個請求,可以設置隊列:[ queue setShouldCancelAllRequestsOnFailure:NO ];
如果想明確取消所有請求:[ queue cancelAllOperations ];
安全的內(nèi)存回收建議
request并沒有retain你的delegate霹娄,所以在沒有請求完的時候釋放了此delegate能犯,需要在dealloc方法里先取消所有請求,再釋放請求實例犬耻,如:
- (void)dealloc
{
[request clearDelegatesAndCancel];
[request release];
...
[super dealloc];
}
向服務器端上傳數(shù)據(jù)
ASIFormDataRequest 踩晶,模擬 Form表單提交,其提交格式與 Header會自動識別枕磁。
沒有文件:application/x-www-form-urlencoded
有文件:multipart/form-data
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:@"Ben" forKey:@"first_name"];
[request setPostValue:@"Copsey" forKey:@"last_name"];
[request setFile:@"/Users/ben/Desktop/ben.jpg" forKey:@"photo"];
[request addData:imageData withFileName:@"george.jpg" andContentType:@"image/jpeg"forKey:@"photos"];
如果要發(fā)送自定義數(shù)據(jù):
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request appendPostData:[@"This is my data" dataUsingEncoding:NSUTF8StringEncoding]];
// Default becomes POST when you use appendPostData: / appendPostDataFromFile: / setPostBody:
[request setRequestMethod:@"PUT"];
下載文件
通過設置request的setDownloadDestinationPath渡蜻,可以設置下載文件用的下載目標目錄。
首先计济,下載過程文件會保存在temporaryFileDownloadPath目錄下茸苇。如果下載完成會做以下事情:
- 如果數(shù)據(jù)是壓縮的,進行解壓沦寂,并把文件放在downloadDestinationPath目錄中学密,臨時文件被刪除
- 如果下載失敗,臨時文件被直接移到downloadDestinationPath目錄凑队,并替換同名文件则果。
如果你想獲取下載中的所有數(shù)據(jù),可以實現(xiàn)delegate中的request:didReceiveData:方法漩氨。但如果你實現(xiàn)了這個方法西壮,request在下載完后,request并不把文件放在downloadDestinationPath中叫惊,需要手工處理款青。
獲取響應信息
信息:status , header, responseEncoding
[request responseStatusCode];
[[request responseHeaders] objectForKey:@"X-Powered-By"];
[request responseEncoding];
獲取請求進度
有兩個回調(diào)方法可以獲取請求進度,
- downloadProgressDelegate霍狰,可以獲取下載進度
- uploadProgressDelegate抡草,可以獲取上傳進度
cookie的支持
如果Cookie存在的話饰及,會把這些信息放在NSHTTPCookieStorage容器中共享,并供下次使用康震。
你可以用[ ASIHTTPRequest setSessionCookies:nil ] ; 清空所有Cookies燎含。
當然,你也可以取消默認的Cookie策略腿短,而使自定義的Cookie:
//Create a cookie
NSDictionary *properties = [[[NSMutableDictionary alloc] init] autorelease];
[properties setValue:[@"Test Value" encodedCookieValue] forKey:NSHTTPCookieValue];
[properties setValue:@"ASIHTTPRequestTestCookie" forKey:NSHTTPCookieName];
[properties setValue:@".allseeing-i.com" forKey:NSHTTPCookieDomain];
[properties setValue:[NSDate dateWithTimeIntervalSinceNow:60*60] forKey:NSHTTPCookieExpires];
[properties setValue:@"/asi-http-request/tests" forKey:NSHTTPCookiePath];
NSHTTPCookie *cookie = [[[NSHTTPCookie alloc] initWithProperties:properties] autorelease];
//This url will return the value of the 'ASIHTTPRequestTestCookie' cookie
url = [NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/read_cookie"];
request = [ASIHTTPRequest requestWithURL:url];
[request setUseCookiePersistence:NO];
[request setRequestCookies:[NSMutableArray arrayWithObject:cookie]];
[request startSynchronous];
//Should be: I have 'Test Value' as the value of 'ASIHTTPRequestTestCookie'
NSLog(@"%@",[request responseString]);
大文件斷點續(xù)傳
0.94以后支持大文件的斷點下載屏箍,只需要設置:
[ request setAllowResumeForFileDownloads:YES ];
[ request setDownloadDestinationPath:downloadPath ];
就可以了。
ASIHTTPRequest會自動保存訪問過的URL信息橘忱,并備之后用赴魁。在以下幾個場景非常有用:
- 當沒有網(wǎng)絡連接的時候。
- 已下載的數(shù)據(jù)再次請求時钝诚,僅當它與本地版本不樣時才進行下載颖御。
ASIDownloadCache 設置下載緩存
它對Get請求的響應數(shù)據(jù)進行緩存(被緩存的數(shù)據(jù)必需是成功的200請求):
[ASIHTTPRequest setDefaultCache:[ASIDownloadCache sharedCache]];
當設置緩存策略后,所有的請求都被自動的緩存起來凝颇。
另外潘拱,如果僅僅希望某次請求使用緩存操作,也可以這樣使用:
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadCache:[ASIDownloadCache sharedCache]];
多種的緩存并存
僅僅需要創(chuàng)建不同的ASIDownloadCache祈噪,并設置緩存所使用的路徑泽铛,并設置到需要使用的request實例中:
ASIDownloadCache *cache = [[[ASIDownloadCache alloc] init] autorelease];
[cache setStoragePath:@"/Users/ben/Documents/Cached-Downloads"];
[self setMyCache:cache];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadCache:[self myCache]];
緩存策略
緩存策略是我們控制緩存行為的主要方式,如:什么時候進行緩存辑鲤,緩存數(shù)據(jù)的利用方式盔腔。
以下是策略可選列表(可組合使用):
如果設置了“defaultCachePolicy”則所有的請求都會使用此緩存。
緩存存儲方式
你可以設置緩存的數(shù)據(jù)需要保存多長時間月褥,ASIHTTPRequest提供了兩種策略:
- ASICacheForSessionDurationCacheStoragePolicy弛随,默認策略,基于session的緩存數(shù)據(jù)存儲宁赤。當下次運行或[ASIHTTPRequest clearSession]時舀透,緩存將失效。
- ASICachePermanentlyCacheStoragePolicy决左,把緩存數(shù)據(jù)永久保存在本地愕够,
如:
ASIHTTPRequest *request = [ ASIHTTPRequest requestWithURL:url ];
[ request setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy ];
另外,也可以使用clearCachedResponsesForStoragePolicy來清空指定策略下的緩存數(shù)據(jù)佛猛。
緩存其它特性
設置是否按服務器在Header里指定的是否可被緩存或過期策略進行緩存:
[[ ASIDownloadCache sharedCache ] setShouldRespectCacheControlHeaders:NO ];
設置request緩存的有效時間:
[ request setSecondsToCache:60*60*24*30 ]; // 緩存30天
可以判斷數(shù)據(jù)是否從緩存讀然蟀拧:
[ request didUseCachedResponse ];
設置緩存所使用的路徑:
[ request setDownloadDestinationPath:[[ ASIDownloadCache sharedCache ] pathToStoreCachedResponseDataForRequest:request ]];
實現(xiàn)自定義的緩存
只要簡單的實現(xiàn)ASICacheDelegate接口就可以被用來使用。
使用代理請求
默認的情況下继找,ASIHTTPRequest會使用被設置的默認代理遂跟。但你也可以手動修改http代理:
// Configure a proxy server manually
NSURL *url = [ NSURL URLWithString:@"http://allseeing-i.com/ignore" ];
ASIHTTPRequest *request = [ ASIHTTPRequest requestWithURL:url ];
[ request setProxyHost:@"192.168.0.1" ];
[ request setProxyPort:3128 ];
// Alternatively, you can use a manually-specified Proxy Auto Config file (PAC)
// (It's probably best if you use a local file)
[request setPACurl:[NSURL URLWithString:@"file:///Users/ben/Desktop/test.pac"]];
ASIHTTPRequest, 請求的其它特性
iOS4中,當應用后臺運行時仍然請求數(shù)據(jù):
[ request setShouldContinueWhenAppEntersBackground:YES ];
是否有網(wǎng)絡請求:
[ ASIHTTPRequest isNetworkInUse ];
是否顯示網(wǎng)絡請求信息在status bar上:
[ ASIHTTPRequest setShouldUpdateNetworkActivityIndicator:NO ];
設置請求超時時,設置重試的次數(shù):
[ request setNumberOfTimesToRetryOnTimeout:2 ];
KeepAlive的支持:
// Set the amount of time to hang on to a persistent connection before it should expire to 2 minutes
[ request setPersistentConnectionTimeoutSeconds:120 ];
// Disable persistent connections entirely
[ request setShouldAttemptPersistentConnection:NO ];
ASIHTTPRequest 一款強大的HTTP包裝開源項目
ASIHTTPRequest幻锁,是一個直接在CFNetwork上做的開源項目凯亮,提供了一個比官方更方便更強大的HTTP網(wǎng)絡傳輸?shù)姆庋b。
特色功能如下:
- 下載的數(shù)據(jù)直接保存到內(nèi)存或文件系統(tǒng)里
- 提供直接提交(HTTP POST)文件的API
- 可以直接訪問與修改HTTP請求與響應HEADER
- 輕松獲取上傳與下載的進度信息
- 異步請求與隊列哄尔,自動管理上傳與下載隊列管理機
- 認證與授權的支持
- Cookie
- 請求與響應的GZIP
- 代理請求
下面來兩個小例子:
NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request start];
NSError *error = [request error];
if (!error) {
NSString *response = [request responseString];
}
當你需要添加更多的請求信息時假消,如,添加個請求Header:
[request addRequestHeader:@"name" value:@"Jory lee"];
添加Post請求時的健值:
[request setPostValue:@"Ben" forKey:@"first_name"];
[request setPostValue:@"Copsey" forKey:@"last_name"];
[request setFile:@"/Users/ben/Desktop/ben.jpg" forKey:@"photo"];
設置HTTP的授權帳號:
[request setUsername:@"username"];
[request setPassword:@"password"];
一個異步請求:
- (IBAction)grabURLInBackground:(id)sender
{
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request startAsynchronous];
}
- (void)requestFinished:(ASIHTTPRequest *)request
{
// Use when fetching text data
NSString *responseString = [request responseString];
// Use when fetching binary data
NSData *responseData = [request responseData];
}
- (void)requestFailed:(ASIHTTPRequest *)request
{
NSError *error = [request error];
}
在我們數(shù)據(jù)獲取的過程中岭接,如果數(shù)據(jù)源復雜置谦,一個請求隊列是必不可少的:
- (IBAction)grabURLInTheBackground:(id)sender
{
if (![self queue]) {
[self setQueue:[[[NSOperationQueue alloc] init] autorelease]];
}
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request setDidFinishSelector:@selector(requestDone:)];
[request setDidFailSelector:@selector(requestWentWrong:)];
[[self queue] addOperation:request]; //queue is an NSOperationQueue
}
- (void)requestDone:(ASIHTTPRequest *)request
{
NSString *response = [request responseString];
}
- (void)requestWentWrong:(ASIHTTPRequest *)request
{
NSError *error = [request error];
}
ASIHTTPRequest -Main classes介紹:
- ASIHTTPRequest:處理與服務器的基本交互,包括下載上傳亿傅,認證,cookies以及進度查看瘟栖。
- ASIFormDataRequest:是ASIHTTPRequest子類葵擎,主要處理post事件,它能使post更加簡單半哟。
- ASINetworkQueue:是NSOperationQueue子類酬滤,當處理多個請求時可以使用,如果每次都是單個請求就不必使用寓涨。
- ASIDownloadCache:該類允許ASIHTTPRequest從服務器傳遞cookie盯串。
ASIHTTPRequest -Support classes介紹:
- ASIInputStream:當使用ASIHTTPRequest上傳數(shù)據(jù)時使用,如果工程中用了ASIHTTPRequest戒良,就一定要include這個類体捏。
- ASIAuthenticationDialog:該類允許ASIHTTPRequest連接到服務器時呈現(xiàn)登錄框。在所有iPhone OS工程中都要使用糯崎,Mac OS工程中可以不用几缭。
- Reachability:相信很多人對這個類已經(jīng)很熟悉了,當在你程序中偵測網(wǎng)絡狀態(tài)時它將非常有用沃呢。
ASIHTTPRequest -Protocols and configuration介紹:
- ASIHTTPRequestDelegate:該協(xié)議指定了ASIHTTPRequest的delegate可能需要實現(xiàn)的方法年栓,所有方法都是optional。
- ASIProgressDelegate:該協(xié)議列出了uploadProgressDelegate和downloadProgressDelegate可能需要實現(xiàn)的方法薄霜,所有方法為optional某抓。
- ASICacheDelegate:該協(xié)議指定了download cache必須實現(xiàn)的方法。如果你要寫你自己的download cache惰瓜,確保實現(xiàn)required方法否副。
- ASIHTTPRequestConfig.h:該文件定義了編譯時所有的全局配置選項。使用該文件中的方法可以在控制臺中輸出request正在進行的任務.