(iphone/ipad開發技術)ASIHTTPRequest 詳解
ASIHTTPRequest 是一款極其強勁的 HTTP 訪問開源專案。讓簡單的 API 完成複雜的功能,如:非同步請求,佇列請求,GZIP 壓縮,快取,斷點續傳,進度跟蹤,上傳檔案,HTTP 認證。在新的版本中,還加入了 Objective-C 閉包 Block 的支援,讓我們的程式碼加輕簡靈活。
下面就舉例說明它的 API 用法。
發起一個同步請求
同步意為著執行緒阻塞,在主執行緒中使用此方法會使應用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 方法啟動同步訪問
- 由於是同步請求,沒有基於事件的回撥方法,所以從 request的error 屬性獲取錯誤資訊
- responseString,為請求的返回 NSString 資訊
建立一個非同步請求
非同步請求的好處是不阻塞當前執行緒,但相對於同步請求略為複雜,至少要新增兩個回撥方法來獲取非同步事件。下面非同步請求程式碼完成上面同樣的一件事情:
- (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 來啟動網路請求
- 在這裡實現了兩個 delegate 的方法,當資料請求成功時會呼叫 requestFinished,請求失敗時(如網路問題或伺服器內部錯誤)會呼叫 requestFailed。
佇列請求
提供了一個對非同步請求更加精準豐富的控制。如:可以設定在佇列中同步請求的連線數。往佇列裡新增的請求例項數大於 maxConcurrentOperationCount 時,請求例項將被置為等待,直到前面至少有一個請求完成並出列才被放到佇列裡執行。這也適用於當我們有多個請求需求按順序執行的時候(可能是業務上的需要,也可能是軟體上的調優),僅僅需要把 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];
}
建立 NSOperationQueue,這個 Cocoa 架構的執行任務(NSOperation)的任務佇列。我們通過 ASIHTTPRequest.h 的原始碼可以看到,此類本身就是一個 NSOperation 的子類。也就是說它可以直接被放到"任務佇列"中並被執行。上面的程式碼除了佇列的建立與新增操作外,其它程式碼與上一例一樣。
佇列非同步請求中中獲取或識別不同request小技巧
- 可以設定一個上下文(userInfo)到 request 物件中,當請求響應完後可以通過訪問 request 物件的 userInfo 獲取裡面的資訊
- 為每一個請求例項設定不同的 setDidFinishSelector / setDidFailSelector 的回撥方法
- 子類化 ASIHTTPRequest,重寫 requestFinished: 與 failWithProblem: 方法
ASINetworkQueues, 它的delegate提供更為豐富的功能
提供的更多的回撥方法如下:
- requestDidStartSelector,請求發起時會調此方法,你可以在此方法中跟據業務選擇性的設定 request 物件的 deleaget
- requestDidReceiveResponseHeadersSelector,當接受完響應的 Header 後設計此方法,這個對下載大資料的時候相當有用,你可以在方法裡做更多業務上的處理
- requestDidFinishSelector,請求並響應成功完成時呼叫此方法
- requestDidFailSelector,請求失敗
- queueDidFinishSelector,整個佇列裡的所有請求都結束時呼叫此方法
它是 NSOperationQueues 的擴充套件,小而強大。但也與它的父類略有區別。如,僅新增到佇列中其實並不能執行請求,只有呼叫[ queue g o ]才會執行;一個正在執行中的佇列,並不需要重複呼叫[ queue go ]。預設情況下,佇列中的一個請求如果失敗,它會取消所有未完成的請求。可以設定[ queue setShouldCancelAllRequestsOnFailure:NO ]來修正。
取消非同步請求
首先,同步請求是不能取消的。
其次,不管是佇列請求,還是簡單的非同步請求,全部呼叫[ request cancel ]來取消請求。取消的請求預設都會按請求失敗處理,並呼叫請求失敗delegate。
如果不想呼叫delegate方法,則設定:[ request clearDelegatesAndCancel];
佇列請求中需要注意的是,如果你取消了一個請求,佇列會自動取消其它所有請求。如果只想取消一個請求,可以設定佇列:[ queue setShouldCancelAllRequestsOnFailure:NO ]; 如果想明確取消所有請求:[ queue cancelAllOperations ];
安全的記憶體回收建議
request並沒有retain你的delegate,所以在沒有請求完的時候釋放了此delegate,需要在dealloc方法裡先取消所有請求,再釋放請求例項,如:
- (void)dealloc
{
[request clearDelegatesAndCancel];
[request release];
...
[super dealloc];
}
向伺服器端上傳資料
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"];
如果要傳送自定義資料:
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目錄下。如果下載完成會做以下事情:
- 如果資料是壓縮的,進行解壓,並把檔案放在 downloadDestinationPath 目錄中,臨時檔案被刪除
- 如果下載失敗,臨時檔案被直接移到 downloadDestinationPath 目錄,並替換同名檔案
如果你想獲取下載中的所有資料,可以實現 delegate 中的 request:didReceiveData:方法。但如果你實現了這個方法,request 在下載完後,request 並不把檔案放在 downloadDestinationPath 中,需要手工處理。
獲取響應資訊
資訊:status , header, responseEncoding
[request responseStatusCode];
[[request responseHeaders] objectForKey:@"X-Powered-By"];
[request responseEncoding];
獲取請求進度
有兩個回撥方法可以獲取請求進度:
- 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]);
大檔案斷點續傳
0.94 以後支援大檔案的斷點下載,只需要設定
[ request setAllowResumeForFileDownloads:YES
];
[ request setDownloadDestinationPath:downloadPath ];
就可以了。
帖子地址 http://www.cocoachina.com/bbs/read.php?tid-51242.html,版權歸 CocoaChina 會員 “旺財勇士” 所有,轉載需聲名
相關文章
- iOS 7: iPhone/iPad應用開發技術詳解iOSiPhoneiPad
- ASIHttpRequest使用詳解HTTP
- 短視訊技術詳解:Android端的短視訊開發技術Android
- 美顏sdk動態貼紙開發技術詳解
- DApp智慧合約技術開發詳情講解APP
- 達贊系統技術開發/達贊DAS模式技術開發詳情模式
- iPhone和iPad應用開發制勝之道iPhoneiPad
- Qt開發技術:Qt拽拖開發(一)拽託框架詳解及DemoQT框架
- 泰山眾籌模式dapp系統開發技術詳解模式APP
- 鏈遊開發:數字藏品開發技術詳情
- JNI技術詳解
- Flutter完整開發實戰詳解(二、 快速開發實戰篇) | 掘金技術徵文Flutter
- 挖礦系統開發技術詳解丨挖礦APP開發原始碼案例APP原始碼
- Followme智慧跟單機器人技術開發/Followme系統開發技術詳情機器人
- 兔子直播卷軸系統技術開發詳情(成熟技術)
- Cube 技術解讀 | Cube 小程式技術詳解
- Cube 技術解讀 | Cube 卡片技術棧詳解
- 量化交易系統python開發技術詳情/量化跟單/合約跟單/開發技術詳情Python
- islandswap鏈遊系統開發技術原理丨islandswap鏈遊系統開發詳解
- SQL 注入技術詳解SQL
- oracle flashback技術詳解Oracle
- 防火牆技術詳解防火牆
- Service Mesh技術詳解
- 量化合約跟單/系統開發技術/跟單機器人/技術開發詳情機器人
- 騰訊魔方《洛克王國》開放世界技術詳解
- Web除錯技術詳解Web除錯
- 詳解Vue.js 技術Vue.js
- web前端技術Mongoose詳解Web前端Go
- 幣幣交易模式系統開發技術丨質押邏輯詳細開發需求講解模式
- TAURO平行宇宙系統技術開發(詳情解析)
- 奈薇緹系統開發技術部署詳情
- NFT數藏商品系統開發技術詳情
- NFT非梵藝術/數藏系統開發/非梵藝術技術開發NFT詳情
- EasyPR--開發詳解(6)SVM開發詳解
- Flutter完整開發實戰詳解(三、 打包與填坑篇)| 掘金技術徵文Flutter
- 深入分析:tp/imtoken/metamask小狐狸錢包系統開發技術詳解
- 佛薩奇合約/系統技術開發/佛薩奇分紅矩陣模式開發技術詳情矩陣模式
- 未來世界商城系統技術開發搭建(詳情)