iOS ASI http 框架詳解
ASIHTTPRequest對CFNetwork API進行了封裝,并且使用起來非常簡單,用Objective-C編寫,可以很好的應用在Mac OS X系統和iOS平臺的應用程序中。ASIHTTPRequest適用于基本的HTTP請求,和基于REST的服務之間的交互。
ASIHTTPRequest功能很強大,主要特色如下:
l 通過簡單的接口,即可完成向服務端提交數據和從服務端獲取數據的工作 l 下載的數據,可存儲到內存中或直接存儲到磁盤中 l 能上傳本地文件到服務端 l 可以方便的訪問和操作請求和返回的Http頭信息 l 可以獲取到上傳或下載的進度信息,為應用程序提供更好的體驗 l 支持上傳或下載隊列,并且可獲取隊列的進度信息 l 支持基本、摘要和NTLM身份認證,在同一會話中授權憑證會自動維持,并且可以存儲在Keychain(Mac和iOS操作系統的密碼管理系統)中 l 支持Cookie l 當應用(iOS 4+)在后臺運行時,請求可以繼續運行 l 支持GZIP壓縮數據 l 內置的ASIDownloadCache類,可以緩存請求返回的數據,這樣即使沒有網絡也可以返回已經緩存的數據結果 l ASIWebPageRequest –可以下載完整的網頁,包括包含的網頁、樣式表、腳本等資源文件,并顯示在UIWebView /WebView中。任意大小的頁面都可以無限期緩存,這樣即使沒有網絡也可以離線瀏覽 l 支持客戶端證書 l 支持通過代理發起Http請求 l 支持帶寬限制。在iOS平臺,可以根據當前網絡情況來自動決定是否限制帶寬,例如當使用WWAN(GPRS/Edge/3G)網絡時限制,而當使用WIFI時不做任何限制 l 支持斷點續傳 l 支持同步和異步請求
往一個Xcode項目中添加第三方類庫文件,有兩種方式:
1. 第一種方式,在Finder中打開需要添加到文件或文件夾,在Xcode中打開要添加文件的項目,然后選中要添加的文件或文件夾,將它從Finder中拖 到Xcode中,然后釋放。在彈出的對話框中,如果文件已經拷貝到了項目文件目錄中,則不需要選中“Copy items”的復選框;如果文件沒有拷貝到項目文件目錄,就需要選中“Copy items”的復選框,這樣Xcode會自動把文件復制到項目文件目錄下。如下圖所示:
2. 第二種方式,在Xcode中,在要添加文件的分組下點右鍵,選中“Add Files to “My Project”…”菜單,在彈出的文件瀏覽對話框中選中要添加到文件或文件夾。如果要添加文件已經拷貝到了項目文件目錄中,則不需要選中“Copy items”的復選框;如果文件沒有拷貝到項目文件目錄,就需要選中“Copy items”的復選框,這樣Xcode會自動把文件復制到項目文件目錄下。如下圖所示:
根據上面的說明,添加ASIHTTPRequest相關文件到Xcode項目中,所需文件列表如下:
ASIHTTPRequestConfig.h
ASIHTTPRequestDelegate.h
ASIProgressDelegate.h
ASICacheDelegate.h
ASIHTTPRequest.h
ASIHTTPRequest.m
ASIDataCompressor.h
ASIDataCompressor.m
ASIDataDecompressor.h
ASIDataDecompressor.m
ASIFormDataRequest.h
ASIInputStream.h
ASIInputStream.m
ASIFormDataRequest.m
ASINetworkQueue.h
ASINetworkQueue.m
ASIDownloadCache.h
ASIDownloadCache.m
ASIAuthenticationDialog.h
ASIAuthenticationDialog.m
Reachability.h (在源碼的 External/Reachability 目錄下)
Reachability.m (在源碼的 External/Reachability 目錄下)
2) 鏈接相關類庫1. 選中項目
2. 選中目標
3. 跳轉到“Build Phases”標簽
4. 展開“Link Binary With Libraries”分組
5. 點擊“+”添加類庫
如下圖所示:
6. 從列表中選擇CFNetwork.framework,然后點擊“Add”按鈕。
7. 按照上一步相同的方法添加:SystemConfiguration.framework, MobileCoreServices.framework,CoreGraphics.framework和libz.1.2.3.dylib這幾個類庫。
8. 添加完后,可以將添加好的一起類庫拖到Xcode項目的Frameworks目錄下
在使用ASIHTTPRequest之前,請確認已經正確安裝,然后在需要應用它的代碼文件頭部,加入:
#import “ASIHTTPRequest.h”
這樣就可以在代碼中使用ASIHTTPRequest相關的類。
</div> 發起一個同步請求同步意為著線程阻塞,在主線程中使用此方法會使應用Hang住而不響應任何用戶事件。所以,在應用程序設計時,大多被用在專門的子線程增加用戶體驗,或用異步請求代替(下面會講到)。
a, 用requestWithURL快捷方法獲取ASIHTTPRequest的一個實例
b, startSynchronous 方法啟動同步訪問,
c, 由于是同步請求,沒有基于事件的回調方法,所以從request的error屬性獲取錯誤信息。
d, responseString,為請求的返回NSString信息。
異步請求的好處是不阻塞當前線程,但相對于同步請求略為復雜,至少要添加兩個回調方法來獲取異步事件。
下面異步請求代碼完成上面同樣的一件事情:
a,與上面不同的地方是指定了一個 "delegate",并用startAsynchronous來啟動網絡請求。
b,在這里實現了兩個delegate的方法,當數據請求成功時會調用requestFinished,請求失敗時(如網絡問題或服務器內部錯誤)會調用requestFailed。
提供了一個對異步請求更加精準豐富的控制。
如,可以設置在隊列中,同步請求的連接數。往隊列里添加的請求實例數大于maxConcurrentOperationCount時,請求實例將被置為等待,直到前面至少有一個請求完成并出列才被放到隊列里執行。
也適用于當我們有多個請求需求按順序執行的時候(可能是業務上的需要,也可能是軟件上的調優),僅僅需要把maxConcurrentOperationCount設為“1”。
創建NSOperationQueue,這個Cocoa架構的執行任務(NSOperation)的任務隊列。我們通過 ASIHTTPRequest.h的源碼可以看到,此類本身就是一個NSOperation的子類。也就是說它可以直接被放到"任務隊列"中,并被執行。 上面的代碼隊了隊列的創建與添加操作外,其它代碼與上一例一樣。
請求隊列上下文a,可以設置一個上下文(userInfo)到request對象中,當請求響應完后可以通過訪問request對象的userInfo獲取里面的信息
b,為每一個請求實例設置不同的setDidFinishSelector / setDidFailSelector的回調方法
c,子類化ASIHTTPRequest,重寫requestFinished: 與 failWithProblem:方法
提供的更多的回調方法如下:
a,requestDidStartSelector,請求發起時會調此方法,你可以在此方法中跟據業務選擇性的設置request對象的deleaget。
b,requestDidReceiveResponseHeadersSelector,當接受完響應的Header后設計此方法,這個對下載大數據的時候相當有用,你可以在方法里做更多業務上的處理。
c,requestDidFinishSelector,請求并響應成功完成時調用此方法
d,requestDidFailSelector,請求失敗
e,queueDidFinishSelector,整個隊列里的所有請求都結束時調用此方法。

默認情況下,隊列中的一個請求如果失敗,它會取消所有未完成的請求。可以設置[ queue setShouldCancelAllRequestsOnFailure:NO ]來修 正。
首先,同步請求是不能取消的。
其次,不管是隊列請求,還是簡單的異步請求,全部調用[ request cancel ]來取消請求。
隊列請求中需要注意的是,如果你取消了一個請求,隊列會自動取消其它所有請求。
如果只想取消一個請求,可以設置隊列:[ queue setShouldCancelAllRequestsOnFailure:NO ];
如果想明確取消所有請求:[ queue cancelAllOperations ];
request并沒有retain你的delegate,所以在沒有請求完的時候釋放了此delegate,需要在dealloc方法里先取消所有請求,再釋放請求實例,如:
ASIFormDataRequest ,模擬 Form表單提交,其提交格式與 Header會自動識別。
沒有文件:application/x-www-form-urlencoded
有文件:multipart/form-data
如果要發送自定義數據:
通過設置request的setDownloadDestinationPath,可以設置下載文件用的下載目標目錄。
首先,下載過程文件會保存在temporaryFileDownloadPath目錄下。如果下載完成會做以下事情:
1,如果數據是壓縮的,進行解壓,并把文件放在downloadDestinationPath目錄中,臨時文件被刪除
2,如果下載失敗,臨時文件被直接移到downloadDestinationPath目錄,并替換同名文件。
如果你想獲取下載中的所有數據,可以實現delegate中的request:didReceiveData:方法。但如果你實現了這個方法,request在下載完后,request并不把文件放在downloadDestinationPath中,需要手工處理。
獲取響應信息信息:status , header, responseEncoding
有兩個回調方法可以獲取請求進度,
1,downloadProgressDelegate,可以獲取下載進度
2,uploadProgressDelegate,可以獲取上傳進度
如果Cookie存在的話,會把這些信息放在NSHTTPCookieStorage容器中共享,并供下次使用。
你可以用[ ASIHTTPRequest setSessionCookies:nil ] ; 清空所有Cookies。
當然,你也可以取消默認的Cookie策略,而使自定義的Cookie:
0.94以后支持大文件的斷點下載,只需要設置:
[ request setAllowResumeForFileDownloads:YES ];
[ request setDownloadDestinationPath:downloadPath ];
就可以了。
ASIHTTPRequest會自動保存訪問過的URL信息,并備之后用。在以下幾個場景非常有用:
1,當沒有網絡連接的時候。
2,已下載的數據再次請求時,僅當它與本地版本不樣時才進行下載。
它對Get請求的響應數據進行緩存(被緩存的數據必需是成功的200請求):
當設置緩存策略后,所有的請求都被自動的緩存起來。
另外,如果僅僅希望某次請求使用緩存操作,也可以這樣使用:
僅僅需要創建不同的ASIDownloadCache,并設置緩存所使用的路徑,并設置到需要使用的request實例中:
緩存策略是我們控制緩存行為的主要方式,如:什么時候進行緩存,緩存數據的利用方式。
以下是策略可選列表(可組合使用):
你可以設置緩存的數據需要保存多長時間,ASIHTTPRequest提供了兩種策略:
a,ASICacheForSessionDurationCacheStoragePolicy,默認策略,基于session的緩存數據存儲。當下次運行或[ASIHTTPRequest clearSession]時,緩存將失效。
b,ASICachePermanentlyCacheStoragePolicy,把緩存數據永久保存在本地,
如:
另外,也可以使用clearCachedResponsesForStoragePolicy來清空指定策略下的緩存數據。
緩存其它特性設置是否按服務器在Header里指定的是否可被緩存或過期策略進行緩存:
設置request緩存的有效時間:
可以判斷數據是否從緩存讀取:
設置緩存所使用的路徑:
只要簡單的實現ASICacheDelegate接口就可以被用來使用。
使用代理請求默認的情況下,ASIHTTPRequest會使用被設置的默認代理。但你也可以手動修改http代理:
iOS4中,當應用后臺運行時仍然請求數據:
是否有網絡請求:
是否顯示網絡請求信息在status bar上:
設置請求超時時,設置重試的次數:
KeepAlive的支持: