詳解iOS - ASIHTTPRequest 網(wǎng)絡(luò)請(qǐng)求
前言
使用 iOS SDK 中的 HTTP 網(wǎng)絡(luò)請(qǐng)求 API,相當(dāng)?shù)膹?fù)雜,調(diào)用很繁瑣,ASIHTTPRequest 就是一個(gè)對(duì) CFNetwork API 進(jìn)行了封裝,并且使用起來非常簡(jiǎn)單的一套 API,外號(hào) “HTTP終結(jié)者”,用 Objective-C 編寫,運(yùn)行效率很高,可以很好的應(yīng)用在 Mac OS X 系統(tǒng)和 iOS 平臺(tái)的應(yīng)用程序中,ASIHTTPRequest 適用于基本的 HTTP 請(qǐng)求,和基于 REST 的服務(wù)之間的交互??上ё髡咴缫淹V垢拢幸恍撛诘?BUG 無(wú)人去解決,很多公司的舊項(xiàng)目里面都?xì)埩糁纳碛埃郧暗暮芏?iOS 項(xiàng)目都是 ASI + SBJson,會(huì)不會(huì)用 ASI,可以算是檢驗(yàn)是否為老牌 iOS 程序員的標(biāo)準(zhǔn)之一。從 iOS 9 開始 CFNetwork 相關(guān)的類和方法開始被廢棄,可以使用 AFNetworking 替換 ASIHTTPRequest 的使用。在 iOS 9+ 中使用 ASIHTTPRequest 無(wú)需對(duì) App Transport Security Settings 添加設(shè)置。
1、ASIHTTPRequest
1.1 ASI 主要特色
- 通過簡(jiǎn)單的接口,即可完成向服務(wù)端提交數(shù)據(jù)和從服務(wù)端獲取數(shù)據(jù)的工作。
- 下載的數(shù)據(jù),可存儲(chǔ)到內(nèi)存中或直接存儲(chǔ)到磁盤中。
- 能上傳本地文件到服務(wù)端。
- 可以方便的訪問和操作請(qǐng)求和返回的 Http 頭信息。
- 可以獲取到上傳或下載的進(jìn)度信息,為應(yīng)用程序提供更好的體驗(yàn)。
- 支持上傳或下載隊(duì)列,并且可獲取隊(duì)列的進(jìn)度信息。
- 支持基本、摘要和 NTLM 身份認(rèn)證,在同一會(huì)話中授權(quán)憑證會(huì)自動(dòng)維持,并且可以存儲(chǔ)在 Keychain(Mac 和 iOS 操作系統(tǒng)的密碼管理系統(tǒng))中。
- 支持 Cookie。
- 當(dāng)應(yīng)用(iOS 4+)在后臺(tái)運(yùn)行時(shí),請(qǐng)求可以繼續(xù)運(yùn)行。
- 支持 GZIP 壓縮數(shù)據(jù)。
- 內(nèi)置的 ASIDownloadCache 類,可以緩存請(qǐng)求返回的數(shù)據(jù),這樣即使沒有網(wǎng)絡(luò)也可以返回已經(jīng)緩存的數(shù)據(jù)結(jié)果。
- ASIWebPageRequest 可以下載完整的網(wǎng)頁(yè),包括包含的網(wǎng)頁(yè)、樣式表、腳本等資源文件,并顯示在 UIWebView /WebView 中。任意大小的頁(yè)面都可以無(wú)限期緩存,這樣即使沒有網(wǎng)絡(luò)也可以離線瀏覽。
- 支持客戶端證書。
- 支持通過代理發(fā)起 Http 請(qǐng)求。
- 支持帶寬限制。在 iOS 平臺(tái),可以根據(jù)當(dāng)前網(wǎng)絡(luò)情況來自動(dòng)決定是否限制帶寬,例如當(dāng)使用 WWAN(GPRS/Edge/3G) 網(wǎng)絡(luò)時(shí)限制,而當(dāng)使用 WIFI 時(shí)不做任何限制。
- 支持?jǐn)帱c(diǎn)續(xù)傳。
- 支持同步和異步請(qǐng)求。
1.2 AFN 與 ASI 的區(qū)別
1、底層實(shí)現(xiàn)
1)AFN 的底層實(shí)現(xiàn)基于 OC 的 NSURLConnection 和 NSURLSession
2)ASI 的底層實(shí)現(xiàn)基于純 C 語(yǔ)言的 CFNetwork 框架
3)因?yàn)?NSURLConnection 和 NSURLSession 是在 CFNetwork 之上的一層封裝,因此 ASI 的運(yùn)行性能高于 AFN
2、對(duì)服務(wù)器返回的數(shù)據(jù)處理
1)ASI 沒有直接提供對(duì)服務(wù)器數(shù)據(jù)處理的方式,直接返回的是 NSData/NSString
2)AFN 提供了多種對(duì)服務(wù)器數(shù)據(jù)處理的方式 (1) JSON 處理-直接返回 NSDictionary 或者 NSArray
(2) XML 處理-返回的是 xml 類型數(shù)據(jù),需對(duì)其進(jìn)行解析
(3) 其他類型數(shù)據(jù)處理
3、監(jiān)聽請(qǐng)求過程 1
)AFN 提供了success 和 failure 兩個(gè) block 來監(jiān)聽請(qǐng)求的過程(只能監(jiān)聽成功和失?。?/p>
- success : 請(qǐng)求成功后調(diào)用
- failure : 請(qǐng)求失敗后調(diào)用
2)ASI 提供了 3 套方案,每一套方案都能監(jiān)聽請(qǐng)求的完整過程(監(jiān)聽請(qǐng)求開始、接收到響應(yīng)頭信息、接受到具體數(shù)據(jù)、接受完畢、請(qǐng)求失敗)
- 成為代理,遵守協(xié)議,實(shí)現(xiàn)協(xié)議中的代理方法
- 成為代理,不遵守協(xié)議,自定義代理方法
- 設(shè)置 block
4、在文件下載和文件上傳的使用難易度
1)AFN
- 不容易實(shí)現(xiàn)監(jiān)聽下載進(jìn)度和上傳進(jìn)度
- 不容易實(shí)現(xiàn)斷點(diǎn)續(xù)傳
- 一般只用來下載不大的文件
2)ASI
- 非常容易實(shí)現(xiàn)下載和上傳
- 非常容易監(jiān)聽下載進(jìn)度和上傳進(jìn)度
- 非常容易實(shí)現(xiàn)斷點(diǎn)續(xù)傳
- 下載大文件或小文件均可
3)實(shí)現(xiàn)下載上傳推薦使用 ASI
5、網(wǎng)絡(luò)監(jiān)控
1)AFN 自己封裝了網(wǎng)絡(luò)監(jiān)控類,易使用
2)ASI 使用的是 Reachability,因?yàn)槭褂?CocoaPods 下載 ASI 時(shí),會(huì)同步下載 Reachability,但 Reachability 作為網(wǎng)絡(luò)監(jiān)控使用較為復(fù)雜(相對(duì)于 AFN 的網(wǎng)絡(luò)監(jiān)控類來說)
3)推薦使用 AFN 做網(wǎng)絡(luò)監(jiān)控 AFNetworkReachabilityManager
6、ASI 提供的其他實(shí)用功能
1)控制信號(hào)旁邊的圈圈要不要在請(qǐng)求過程中轉(zhuǎn)
2)可以輕松地設(shè)置請(qǐng)求之間的依賴:每一個(gè)請(qǐng)求都是一個(gè) NSOperation 對(duì)象
3)可以統(tǒng)一管理所有請(qǐng)求(還專門提供了一個(gè)叫做 ASINetworkQueue 來管理所有的請(qǐng)求對(duì)象) 暫停/恢復(fù)/取消所有的請(qǐng)求
監(jiān)聽整個(gè)隊(duì)列中所有請(qǐng)求的下載進(jìn)度和上傳進(jìn)度
2、ASIHTTPRequest 的使用
2.1 添加 ASIHTTPRequest
Github 網(wǎng)址: https://github.com/pokeb/asi-http-request
https://allseeing-i.com/ASIHTTPRequest/
ASIHTTPRequest 系統(tǒng)需求:
| ASIHTTPRequest Version | Minimum iOS Target | Target Notes |
|---|---|---|
| 1.8.1 -> 1.8.2 | iOS 3.0+ | |
| 0.2 -> 1.8.0 |
ASIHTTPRequest 使用 MRC
Objective-C
// 添加系統(tǒng)庫(kù)文件 CFNetwork.framework SystemConfiguration.framework MobileCoreServices.framework CoreGraphics.framework libz.1.1.3.tbd libxml2.2.tbd // 添加第三方庫(kù)文件 ASIHTTPRequest-1.8.2 // 在 TARGETS -> Builed Settings -> Search Paths -> Header Search Paths 中添加文件路徑 /usr/include/libxml2 // 在 TARGETS -> Build Phases -> Compile Sources -> ...in .../ASIHTTPRequest 后添加 -fno-objc-arc // 包含頭文件 #import "ASIHTTPRequest.h" #import "ASIFormDataRequest.h"
2.2 ASIHTTPRequest 的設(shè)置
Objective-C
// 設(shè)置請(qǐng)求頭
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://api.hudong.com/iphonexml.do?type=focus-c"]];
[request addRequestHeader:@"Referer" value:@"http://www.dreamingwish.com/"];
// 設(shè)置應(yīng)用后臺(tái)運(yùn)行時(shí)是否仍然請(qǐng)求數(shù)據(jù)
request.shouldContinueWhenAppEntersBackground = YES;
// 設(shè)置請(qǐng)求超時(shí)時(shí)重試的次數(shù)
request.numberOfTimesToRetryOnTimeout = 3;
// 設(shè)置 KeepAlive 支持
// Set the amount of time to hang on to a persistent connection before it should expire to 2 minutes
request.persistentConnectionTimeoutSeconds = 120;
// Disable persistent connections entirely
request.shouldAttemptPersistentConnection = NO;
// 設(shè)置是否顯示網(wǎng)絡(luò)請(qǐng)求信息在 status bar 上
[ASIHTTPRequest setShouldUpdateNetworkActivityIndicator:NO];
// 網(wǎng)絡(luò)狀態(tài)檢查
BOOL isNetworkInUse = [ASIHTTPRequest isNetworkInUse];
3、ASI 同步 GET 請(qǐng)求
這是 ASIHTTPRequest 最簡(jiǎn)單的一種使用模式,發(fā)送 startSynchronous 消息后即開始在同一線程中執(zhí)行 HTTP 請(qǐng)求,線程將一直等待直到請(qǐng)求結(jié)束(請(qǐng)求成功或者失?。Mㄟ^檢查 error 屬性可以判斷請(qǐng)求是否成功或者有錯(cuò)誤發(fā)生。
要獲取返回的文本信息,調(diào)用 responseString 方法。如果下載的是二進(jìn)制文件,例如圖片、MP3,則調(diào)用 responseData 方法,可以得到一個(gè) NSData 對(duì)象。
一般情況下,應(yīng)該優(yōu)先使用異步請(qǐng)求代替同步請(qǐng)求,當(dāng)在主線程中使用 ASIHTTPRequest 同步請(qǐng)求會(huì)阻塞主線程的執(zhí)行,這導(dǎo)致用戶界面不響應(yīng)用戶操作,任何動(dòng)畫都會(huì)停止渲染,直到請(qǐng)求完成。
Objective-C
數(shù)據(jù)請(qǐng)求
NSURL *url = [NSURL URLWithString:@"http://api.hudong.com/iphonexml.do?type=focus-c"];
// 創(chuàng)建請(qǐng)求
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
// 設(shè)置超時(shí)時(shí)間,可不設(shè)置,使用默認(rèn)
request.timeOutSeconds = 5;
// 發(fā)送同步請(qǐng)求
[request startSynchronous];
// 獲得錯(cuò)誤信息
NSError *error = [request error];
// 網(wǎng)絡(luò)請(qǐng)求失敗
if (error) {
// 網(wǎng)絡(luò)請(qǐng)求成功
NSLog(@"網(wǎng)絡(luò)請(qǐng)求失敗:\n%@", error);
} else {
// 獲得服務(wù)器的響應(yīng),字符串格式
NSString *responseString = [request responseString];
NSLog(@"網(wǎng)絡(luò)請(qǐng)求成功:\n%@", responseString);
// 獲得服務(wù)器的響應(yīng),NSData 格式
NSData *responseData = [request responseData];
textView.text = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
}
文件下載
通過設(shè)置 request 的 setDownloadDestinationPath,可以設(shè)置下載文件用的下載目標(biāo)目錄。首先,下載過程文件會(huì)保存在 temporaryFileDownloadPath 目錄下。如果下載完成會(huì)做以下事情:
1,如果數(shù)據(jù)是壓縮的,進(jìn)行解壓,并把文件放在 downloadDestinationPath 目錄中,臨時(shí)文件被刪除。
2,如果下載失敗,臨時(shí)文件被直接移到 downloadDestinationPath 目錄,并替換同名文件。
如果你想獲取下載中的所有數(shù)據(jù),可以實(shí)現(xiàn) delegate 中的 request:didReceiveData:方法。但如果你實(shí)現(xiàn)了這個(gè)方法,request 在下載完后,request 并不把文件放在 downloadDestinationPath中,需要手工處理。
NSURL *url = [NSURL URLWithString:@"http://www.dreamingwish.com/wp-content/uploads/2011/10/asihttprequest-auth.png"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
// 設(shè)置文件存儲(chǔ)路徑
[request setDownloadDestinationPath:@"/Users/JHQ0228/Desktop/asi.png"];
[request startSynchronous];
// 獲得錯(cuò)誤信息
NSError *error = [request error];
// 網(wǎng)絡(luò)請(qǐng)求失敗
if (error) {
NSLog(@"網(wǎng)絡(luò)請(qǐng)求失敗:\n%@", error);
} else {
// 網(wǎng)絡(luò)請(qǐng)求成功
NSLog(@"網(wǎng)絡(luò)請(qǐng)求成功:\n");
}
4、ASI 異步 GET 請(qǐng)求
請(qǐng)求在后臺(tái)線程中運(yùn)行,當(dāng)請(qǐng)求執(zhí)行完后再通知調(diào)用的線程。這樣不會(huì)導(dǎo)致主線程進(jìn)行網(wǎng)絡(luò)請(qǐng)求時(shí),界面被鎖定等情況。
1、協(xié)議方式
在這里實(shí)現(xiàn)了兩個(gè) delegate 的方法,當(dāng)數(shù)據(jù)請(qǐng)求成功時(shí)會(huì)調(diào)用 requestFinished,請(qǐng)求失敗時(shí)(如網(wǎng)絡(luò)問題或服務(wù)器內(nèi)部錯(cuò)誤)會(huì)調(diào)用 requestFailed。
NSURL *url = [NSURL URLWithString:@"http://api.hudong.com/iphonexml.do?type=focus-c"];
// 創(chuàng)建請(qǐng)求
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
// 設(shè)置超時(shí)時(shí)間,可不設(shè)置,使用默認(rèn)
request.timeOutSeconds = 5;
// 設(shè)置代理,需遵守 <ASIHTTPRequestDelegate> 協(xié)議
request.delegate = self;
// 發(fā)送異步請(qǐng)求
[request startAsynchronous];
// 網(wǎng)絡(luò)請(qǐng)求成功,協(xié)議方法
- (void)requestFinished:(ASIHTTPRequest *)request {
}
// 網(wǎng)絡(luò)請(qǐng)求失敗,協(xié)議方法
- (void)requestFailed:(ASIHTTPRequest *)request {
}
2、Block 方式
在平臺(tái)支持情況下,ASIHTTPRequest 1.8 以上支持 block。
NSURL *url = [NSURL URLWithString:@"http://api.hudong.com/iphonexml.do?type=focus-c"];
// 創(chuàng)建請(qǐng)求,加 __weak 除去 block 循環(huán)調(diào)用警告
__weak ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
// 設(shè)置超時(shí)時(shí)間,可不設(shè)置,使用默認(rèn)
request.timeOutSeconds = 5;
// 發(fā)送異步請(qǐng)求
[request startAsynchronous];
// 網(wǎng)絡(luò)請(qǐng)求成功
[request setCompletionBlock:^{
}];
// 網(wǎng)絡(luò)請(qǐng)求失敗
[request setFailedBlock:^{
}];
5、ASI POST 請(qǐng)求
1、POST 表單
ASIFormDataRequest,模擬 Form 表單提交,其提交格式與 Header 會(huì)自動(dòng)識(shí)別。文件中的數(shù)據(jù)是需要時(shí)才從磁盤加載,所以只要 web server 能處理,那么上傳大文件是沒有問題的。
// 通常數(shù)據(jù)是以 'application/x-www-form-urlencoded' 格式發(fā)送的,如果上傳了二進(jìn)制數(shù)據(jù)或者文件,那么格式將自動(dòng)變?yōu)?‘multipart/form-data'。
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:@"http://www.dreamingwish.com"]];
// 沒有文件
[request setPostValue:@"Ben" forKey:@"first_name"];
[request setPostValue:@"Copsey" forKey:@"last_name"];
// 發(fā)送文件
[request setFile:@"/Users/ben/Desktop/ben.jpg" forKey:@"photo"];
// 數(shù)據(jù)的 mime 頭是自動(dòng)判定的,但是如果你想自定義mime頭,那么這樣:
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:@"http://www.dreamingwish.com"]];
// Upload a file on disk
[request setFile:@"/Users/ben/Desktop/ben.jpg" withFileName:@"myphoto.jpg" andContentType:@"image/jpeg" forKey:@"photo"];
// Upload an NSData instance
NSData *imageData = UIImagePNGRepresentation([UIImage imageNamed:@"myphoto.jpg"]);
[request setData:imageData withFileName:@"myphoto.jpg" andContentType:@"image/jpeg" forKey:@"photo"];
// 你可以使用 addPostValue 方法來發(fā)送相同 name 的多個(gè)數(shù)據(jù):
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:@"http://www.dreamingwish.com"]];
[request addPostValue:@"Ben" forKey:@"names"];
[request addPostValue:@"George" forKey:@"names"];
2、PUT 請(qǐng)求、自定義 POST 請(qǐng)求
如果你想發(fā)送 PUT 請(qǐng)求,或者你想自定義 POST 請(qǐng)求,使用 appendPostData: 或者 appendPostDataFromFile:
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@"http://www.dreamingwish.com"]]; [request appendPostData:[@"This is my data" dataUsingEncoding:NSUTF8StringEncoding]]; // Default becomes POST when you use appendPostData: / appendPostDataFromFile: / setPostBody: [request setRequestMethod:@"PUT"];
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
配置iOS?16?屏幕旋轉(zhuǎn)適配實(shí)例詳解
這篇文章主要為大家介紹了配置iOS?16?屏幕旋轉(zhuǎn)適配實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
UILabel顯示定時(shí)器文本跳動(dòng)問題的解決方法
這篇文章主要給大家介紹了關(guān)于UILabel顯示定時(shí)器文本跳動(dòng)問題的解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)各位iOS開發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07
iOS WKWebView中MessageHandler內(nèi)存泄漏問題的完美解決過程
這篇文章主要給大家介紹了關(guān)于iOS WKWebView中MessageHandler內(nèi)存泄漏問題的完美解決過程,文中通過示例代碼介紹的非常詳細(xì),對(duì)各位iOS開發(fā)者們具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07
iOS開發(fā)網(wǎng)絡(luò)篇—實(shí)現(xiàn)大文件的多線程斷點(diǎn)下載
iOS開發(fā)中經(jīng)常會(huì)用到文件的下載功能,這篇文章主要介紹了iOS開發(fā)網(wǎng)絡(luò)篇—實(shí)現(xiàn)大文件的多線程斷點(diǎn)下載,今天咱們來分享一下思路。2016-11-11
iOS布局渲染之UIView方法的調(diào)用時(shí)機(jī)詳解
在你剛開始開發(fā) iOS 應(yīng)用時(shí),最難避免或者是調(diào)試的就是和布局相關(guān)的問題,下面這篇文章主要給大家介紹了關(guān)于iOS布局渲染之UIView方法調(diào)用時(shí)機(jī)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2018-07-07
iOS開發(fā)之TableView實(shí)現(xiàn)完整的分割線詳解
在iOS開發(fā)中, tableView是我們最常用的UI控件之一。所以這篇文章主要給大家詳細(xì)介紹了關(guān)于iOS中的TableView分割線,有需要的朋友們可以參考借鑒,下面來一起看看吧。2016-12-12
iOS App使用GCD導(dǎo)致的卡頓現(xiàn)象及解決方法
這篇文章主要給大家介紹了關(guān)于iOS App使用GCD導(dǎo)致的卡頓現(xiàn)象及解決方法的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-07-07

