前言
使用 iOS SDK 中的 HTTP 網(wǎng)絡請求 API,相當?shù)膹碗s,調(diào)用很繁瑣,ASIHTTPRequest 就是一個對 CFNetwork API 進行了封裝,并且使用起來非常簡單的一套 API,外號 “HTTP終結者”,用 Objective-C 編寫,運行效率很高,可以很好的應用在 Mac OS X 系統(tǒng)和 iOS 平臺的應用程序中,ASIHTTPRequest 適用于基本的 HTTP 請求,和基于 REST 的服務之間的交互。可惜作者早已停止更新,有一些潛在的 BUG 無人去解決,很多公司的舊項目里面都殘留著它的身影,以前的很多 iOS 項目都是 ASI + SBJson,會不會用 ASI,可以算是檢驗是否為老牌 iOS 程序員的標準之一。從 iOS 9 開始 CFNetwork 相關的類和方法開始被廢棄,可以使用 AFNetworking 替換 ASIHTTPRequest 的使用。在 iOS 9+ 中使用 ASIHTTPRequest 無需對 App Transport Security Settings 添加設置。
1、ASIHTTPRequest
1.1 ASI 主要特色
- 通過簡單的接口,即可完成向服務端提交數(shù)據(jù)和從服務端獲取數(shù)據(jù)的工作。
- 下載的數(shù)據(jù),可存儲到內(nèi)存中或直接存儲到磁盤中。
- 能上傳本地文件到服務端。
- 可以方便的訪問和操作請求和返回的 Http 頭信息。
- 可以獲取到上傳或下載的進度信息,為應用程序提供更好的體驗。
- 支持上傳或下載隊列,并且可獲取隊列的進度信息。
- 支持基本、摘要和 NTLM 身份認證,在同一會話中授權憑證會自動維持,并且可以存儲在 Keychain(Mac 和 iOS 操作系統(tǒng)的密碼管理系統(tǒng))中。
- 支持 Cookie。
- 當應用(iOS 4+)在后臺運行時,請求可以繼續(xù)運行。
- 支持 GZIP 壓縮數(shù)據(jù)。
- 內(nèi)置的 ASIDownloadCache 類,可以緩存請求返回的數(shù)據(jù),這樣即使沒有網(wǎng)絡也可以返回已經(jīng)緩存的數(shù)據(jù)結果。
- ASIWebPageRequest 可以下載完整的網(wǎng)頁,包括包含的網(wǎng)頁、樣式表、腳本等資源文件,并顯示在 UIWebView /WebView 中。任意大小的頁面都可以無限期緩存,這樣即使沒有網(wǎng)絡也可以離線瀏覽。
- 支持客戶端證書。
- 支持通過代理發(fā)起 Http 請求。
- 支持帶寬限制。在 iOS 平臺,可以根據(jù)當前網(wǎng)絡情況來自動決定是否限制帶寬,例如當使用 WWAN(GPRS/Edge/3G) 網(wǎng)絡時限制,而當使用 WIFI 時不做任何限制。
- 支持斷點續(xù)傳。
- 支持同步和異步請求。
1.2 AFN 與 ASI 的區(qū)別
1、底層實現(xiàn)
1)AFN 的底層實現(xiàn)基于 OC 的 NSURLConnection 和 NSURLSession
2)ASI 的底層實現(xiàn)基于純 C 語言的 CFNetwork 框架
3)因為 NSURLConnection 和 NSURLSession 是在 CFNetwork 之上的一層封裝,因此 ASI 的運行性能高于 AFN
2、對服務器返回的數(shù)據(jù)處理
1)ASI 沒有直接提供對服務器數(shù)據(jù)處理的方式,直接返回的是 NSData/NSString
2)AFN 提供了多種對服務器數(shù)據(jù)處理的方式 (1) JSON 處理-直接返回 NSDictionary 或者 NSArray
(2) XML 處理-返回的是 xml 類型數(shù)據(jù),需對其進行解析
(3) 其他類型數(shù)據(jù)處理
3、監(jiān)聽請求過程 1
)AFN 提供了success 和 failure 兩個 block 來監(jiān)聽請求的過程(只能監(jiān)聽成功和失敗)
- success : 請求成功后調(diào)用
- failure : 請求失敗后調(diào)用
2)ASI 提供了 3 套方案,每一套方案都能監(jiān)聽請求的完整過程(監(jiān)聽請求開始、接收到響應頭信息、接受到具體數(shù)據(jù)、接受完畢、請求失敗)
- 成為代理,遵守協(xié)議,實現(xiàn)協(xié)議中的代理方法
- 成為代理,不遵守協(xié)議,自定義代理方法
- 設置 block
4、在文件下載和文件上傳的使用難易度
1)AFN
- 不容易實現(xiàn)監(jiān)聽下載進度和上傳進度
- 不容易實現(xiàn)斷點續(xù)傳
- 一般只用來下載不大的文件
2)ASI
- 非常容易實現(xiàn)下載和上傳
- 非常容易監(jiān)聽下載進度和上傳進度
- 非常容易實現(xiàn)斷點續(xù)傳
- 下載大文件或小文件均可
3)實現(xiàn)下載上傳推薦使用 ASI
5、網(wǎng)絡監(jiān)控
1)AFN 自己封裝了網(wǎng)絡監(jiān)控類,易使用
2)ASI 使用的是 Reachability,因為使用 CocoaPods 下載 ASI 時,會同步下載 Reachability,但 Reachability 作為網(wǎng)絡監(jiān)控使用較為復雜(相對于 AFN 的網(wǎng)絡監(jiān)控類來說)
3)推薦使用 AFN 做網(wǎng)絡監(jiān)控 AFNetworkReachabilityManager
6、ASI 提供的其他實用功能
1)控制信號旁邊的圈圈要不要在請求過程中轉(zhuǎn)
2)可以輕松地設置請求之間的依賴:每一個請求都是一個 NSOperation 對象
3)可以統(tǒng)一管理所有請求(還專門提供了一個叫做 ASINetworkQueue 來管理所有的請求對象) 暫停/恢復/取消所有的請求
監(jiā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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
// 添加系統(tǒng)庫文件 CFNetwork.framework SystemConfiguration.framework MobileCoreServices.framework CoreGraphics.framework libz.1.1.3.tbd libxml2.2.tbd // 添加第三方庫文件 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 的設置
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
// 設置請求頭 ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:@ "http://api.hudong.com/iphonexml.do?type=focus-c" ]]; [request addRequestHeader:@ "Referer" value:@ "http://www.dreamingwish.com/" ]; // 設置應用后臺運行時是否仍然請求數(shù)據(jù) request.shouldContinueWhenAppEntersBackground = YES; // 設置請求超時時重試的次數(shù) request.numberOfTimesToRetryOnTimeout = 3; // 設置 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; // 設置是否顯示網(wǎng)絡請求信息在 status bar 上 [ASIHTTPRequest setShouldUpdateNetworkActivityIndicator:NO]; // 網(wǎng)絡狀態(tài)檢查 BOOL isNetworkInUse = [ASIHTTPRequest isNetworkInUse]; |
3、ASI 同步 GET 請求
這是 ASIHTTPRequest 最簡單的一種使用模式,發(fā)送 startSynchronous 消息后即開始在同一線程中執(zhí)行 HTTP 請求,線程將一直等待直到請求結束(請求成功或者失敗)。通過檢查 error 屬性可以判斷請求是否成功或者有錯誤發(fā)生。
要獲取返回的文本信息,調(diào)用 responseString 方法。如果下載的是二進制文件,例如圖片、MP3,則調(diào)用 responseData 方法,可以得到一個 NSData 對象。
一般情況下,應該優(yōu)先使用異步請求代替同步請求,當在主線程中使用 ASIHTTPRequest 同步請求會阻塞主線程的執(zhí)行,這導致用戶界面不響應用戶操作,任何動畫都會停止渲染,直到請求完成。
Objective-C
數(shù)據(jù)請求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
NSURL *url = [NSURL URLWithString:@ "http://api.hudong.com/iphonexml.do?type=focus-c" ]; // 創(chuàng)建請求 ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; // 設置超時時間,可不設置,使用默認 request.timeOutSeconds = 5; // 發(fā)送同步請求 [request startSynchronous]; // 獲得錯誤信息 NSError *error = [request error]; // 網(wǎng)絡請求失敗 if (error) { // 網(wǎng)絡請求成功 NSLog(@ "網(wǎng)絡請求失敗:\n%@" , error); } else { // 獲得服務器的響應,字符串格式 NSString *responseString = [request responseString]; NSLog(@ "網(wǎng)絡請求成功:\n%@" , responseString); // 獲得服務器的響應,NSData 格式 NSData *responseData = [request responseData]; textView.text = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; } |
文件下載
通過設置 request 的 setDownloadDestinationPath,可以設置下載文件用的下載目標目錄。首先,下載過程文件會保存在 temporaryFileDownloadPath 目錄下。如果下載完成會做以下事情:
1,如果數(shù)據(jù)是壓縮的,進行解壓,并把文件放在 downloadDestinationPath 目錄中,臨時文件被刪除。
2,如果下載失敗,臨時文件被直接移到 downloadDestinationPath 目錄,并替換同名文件。
如果你想獲取下載中的所有數(shù)據(jù),可以實現(xiàn) delegate 中的 request:didReceiveData:方法。但如果你實現(xiàn)了這個方法,request 在下載完后,request 并不把文件放在 downloadDestinationPath中,需要手工處理。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
NSURL *url = [NSURL URLWithString:@ "http://www.dreamingwish.com/wp-content/uploads/2011/10/asihttprequest-auth.png" ]; ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; // 設置文件存儲路徑 [request setDownloadDestinationPath:@ "/Users/JHQ0228/Desktop/asi.png" ]; [request startSynchronous]; // 獲得錯誤信息 NSError *error = [request error]; // 網(wǎng)絡請求失敗 if (error) { NSLog(@ "網(wǎng)絡請求失敗:\n%@" , error); } else { // 網(wǎng)絡請求成功 NSLog(@ "網(wǎng)絡請求成功:\n" ); } |
4、ASI 異步 GET 請求
請求在后臺線程中運行,當請求執(zhí)行完后再通知調(diào)用的線程。這樣不會導致主線程進行網(wǎng)絡請求時,界面被鎖定等情況。
1、協(xié)議方式
在這里實現(xiàn)了兩個 delegate 的方法,當數(shù)據(jù)請求成功時會調(diào)用 requestFinished,請求失敗時(如網(wǎng)絡問題或服務器內(nèi)部錯誤)會調(diào)用 requestFailed。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
NSURL *url = [NSURL URLWithString:@ "http://api.hudong.com/iphonexml.do?type=focus-c" ]; // 創(chuàng)建請求 ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; // 設置超時時間,可不設置,使用默認 request.timeOutSeconds = 5; // 設置代理,需遵守 <ASIHTTPRequestDelegate> 協(xié)議 request.delegate = self; // 發(fā)送異步請求 [request startAsynchronous]; // 網(wǎng)絡請求成功,協(xié)議方法 - ( void )requestFinished:(ASIHTTPRequest *)request { } // 網(wǎng)絡請求失敗,協(xié)議方法 - ( void )requestFailed:(ASIHTTPRequest *)request { } |
2、Block 方式
在平臺支持情況下,ASIHTTPRequest 1.8 以上支持 block。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
NSURL *url = [NSURL URLWithString:@ "http://api.hudong.com/iphonexml.do?type=focus-c" ]; // 創(chuàng)建請求,加 __weak 除去 block 循環(huán)調(diào)用警告 __weak ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; // 設置超時時間,可不設置,使用默認 request.timeOutSeconds = 5; // 發(fā)送異步請求 [request startAsynchronous]; // 網(wǎng)絡請求成功 [request setCompletionBlock:^{ }]; // 網(wǎng)絡請求失敗 [request setFailedBlock:^{ }]; |
5、ASI POST 請求
1、POST 表單
ASIFormDataRequest,模擬 Form 表單提交,其提交格式與 Header 會自動識別。文件中的數(shù)據(jù)是需要時才從磁盤加載,所以只要 web server 能處理,那么上傳大文件是沒有問題的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
// 通常數(shù)據(jù)是以 'application/x-www-form-urlencoded' 格式發(fā)送的,如果上傳了二進制數(shù)據(jù)或者文件,那么格式將自動變?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 頭是自動判定的,但是如果你想自定義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 的多個數(shù)據(jù): ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:[NSURL URLWithString:@ "http://www.dreamingwish.com" ]]; [request addPostValue:@ "Ben" forKey:@ "names" ]; [request addPostValue:@ "George" forKey:@ "names" ]; |
2、PUT 請求、自定義 POST 請求
如果你想發(fā)送 PUT 請求,或者你想自定義 POST 請求,使用 appendPostData: 或者 appendPostDataFromFile:
1
2
3
4
5
6
|
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" ]; |
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:http://www.cnblogs.com/QianChia/p/5766962.html