(轉) IOS ASI http 架構詳解

來源:互聯網
上載者:User

標籤:des   c   class   blog   code   java   

(轉) 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 支援同步和非同步請求

 

 

1) 添加檔案

 

往一個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相關的類。

發起一個同步請求

同步意為著線程阻塞,在主線程中使用此方法會使應用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];  }}

a, 用requestWithURL快捷方法擷取ASIHTTPRequest的一個執行個體
b, startSynchronous 方法啟動同步訪問,
c, 由於是同步請求,沒有基於事件的回調方法,所以從request的error屬性擷取錯誤資訊。
d, 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];}

a,與上面不同的地方是指定了一個 "delegate",並用startAsynchronous來啟動網路請求。
b,在這裡實現了兩個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的子類。也就是說它可以直接被放到"任務隊列"中,並被執行。上面的代碼隊了隊列的建立與添加操作外,其它代碼與上一例一樣。

請求隊列上下文

a,可以設定一個上下文(userInfo)到request對象中,當請求響應完後可以通過訪問request對象的userInfo擷取裡面的資訊
b,為每一個請求執行個體設定不同的setDidFinishSelector / setDidFailSelector的回調方法
c,子類化ASIHTTPRequest,重寫requestFinished: 與 failWithProblem:方法

ASINetworkQueues, 它的delegate提供更為豐富的功能

提供的更多的回調方法如下:
a,requestDidStartSelector,請求發起時會調此方法,你可以在此方法中跟據業務選擇性的設定request對象的deleaget。
b,requestDidReceiveResponseHeadersSelector,當接受完響應的Header後設計此方法,這個對下載大資料的時候相當有用,你可以在方法裡做更多業務上的處理。
c,requestDidFinishSelector,請求並響應成功完成時調用此方法
d,requestDidFailSelector,請求失敗
e,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];   ...   [superdealloc];}

向伺服器端上傳資料

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目錄下。如果下載完成會做以下事情:
1,如果資料是壓縮的,進行解壓,並把檔案放在downloadDestinationPath目錄中,臨時檔案被刪除
2,如果下載失敗,臨時檔案被直接移到downloadDestinationPath目錄,並替換同名檔案。

如果你想擷取下載中的所有資料,可以實現delegate中的request:didReceiveData:方法。但如果你實現了這個方法,request在下載完後,request並不把檔案放在downloadDestinationPath中,需要手工處理。

擷取響應資訊

資訊:status , header, responseEncoding

[request responseStatusCode];[[request responseHeaders] objectForKey:@"X-Powered-By"]; [request responseEncoding];

擷取請求進度

有兩個回調方法可以擷取請求進度,
1,downloadProgressDelegate,可以擷取下載進度
2,uploadProgressDelegate,可以擷取上傳進度

cookie的支援

如果Cookie存在的話,會把這些資訊放在NSHTTPCookieStorage容器中共用,並供下次使用。
你可以用[ ASIHTTPRequest setSessionCookies:nil ] ; 清空所有Cookies。
當然,你也可以取消預設的Cookie策略,而使自訂的Cookie:

//Create a cookieNSDictionary *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‘ cookieurl = [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 ];
就可以了。

ASIHTTPRequest會自動儲存訪問過的URL資訊,並備之後用。在以下幾個情境非常有用:
1,當沒有網路連接的時候。
2,已下載的資料再次請求時,僅當它與本地版本不樣時才進行下載。

ASIDownloadCache 設定下載快取

它對Get請求的響應資料進行緩衝(被緩衝的資料必需是成功的200請求):

[ASIHTTPRequest setDefaultCache:[ASIDownloadCache sharedCache]];

當設定緩衝策略後,所有的請求都被自動的緩衝起來。
另外,如果僅僅希望某次請求使用快取作業,也可以這樣使用:

ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];[request setDownloadCache:[ASIDownloadCache sharedCache]];

多種的緩衝並存

僅僅需要建立不同的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]];

緩衝策略

緩衝策略是我們控制緩衝行為的主要方式,如:什麼時候進行緩衝,快取資料的利用方式。
以下是策略可選列表(可組合使用):

ASIUseDefaultCachePolicy這是一個預設的緩衝策略“ASIAskServerIfModifiedWhenStaleCachePolicy”,這個很明白,見名知意(它不能與其它策略組合使用)ASIDoNotReadFromCacheCachePolicy所讀資料不使用緩衝ASIDoNotWriteToCacheCachePolicy不對快取資料進行寫操作ASIAskServerIfModifiedWhenStaleCachePolicy預設緩衝行為,request會先判斷是否存在快取資料。a, 如果沒有再進行網路請求。 b,如果存在快取資料,並且資料沒有到期,則使用緩衝。c,如果存在快取資料,但已經到期,request會先進行網路請求,判斷伺服器版本與本地版本是否一樣,如果一樣,則使用緩衝。如果伺服器有新版本,會進行網路請求,並更新本機快取ASIAskServerIfModifiedCachePolicy與預設緩衝大致一樣,區別僅是每次請求都會 去伺服器判斷是否有更新ASIOnlyLoadIfNotCachedCachePolicy如果有緩衝在本地,不管其到期與否,總會拿來使用ASIDontLoadCachePolicy僅當有緩衝的時候才會被正確執行,如果沒有緩衝,request將被取消(沒有錯誤資訊)ASIFallbackToCacheIfLoadFailsCachePolicy這個選項經常被用來與其它選項組合使用。請求失敗時,如果有緩衝當網路則返回本機快取資訊(這個在處理異常時非常有用)如果設定了“defaultCachePolicy”則所有的請求都會使用此緩衝。

緩衝儲存方式

你可以設定緩衝的資料需要儲存多長時間,ASIHTTPRequest提供了兩種策略:
a,ASICacheForSessionDurationCacheStoragePolicy,預設策略,基於session的快取資料儲存。當下次運行或[ASIHTTPRequest clearSession]時,緩衝將失效。
b,ASICachePermanentlyCacheStoragePolicy,把快取資料永久儲存在本地,
如:

ASIHTTPRequest *request = [ ASIHTTPRequest requestWithURL:url ];[ request setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy ];

另外,也可以使用clearCachedResponsesForStoragePolicy來清空指定策略下的快取資料。

緩衝其它特性

設定是否按伺服器在Header裡指定的是否可被緩衝或到期策略進行緩衝:

[[ ASIDownloadCache sharedCache ] setShouldRespectCacheControlHeaders:NO ];

設定request緩衝的有效時間:

[ request setSecondsToCache:60*60*24*30];// 緩衝30天

可以判斷資料是否從緩衝讀取:

[ request didUseCachedResponse ];

設定緩衝所使用的路徑:

[ request setDownloadDestinationPath:[[ ASIDownloadCache sharedCache ] pathToStoreCachedResponseDataForRequest:request ]];

實現自訂的緩衝

只要簡單的實現ASICacheDelegate介面就可以被用來使用。

使用代理請求

預設的情況下,ASIHTTPRequest會使用被設定的預設代理。但你也可以手動修改http代理:

// Configure a proxy server manuallyNSURL *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中,當應用後台運行時仍然請求資料:

[ request setShouldContinueWhenAppEntersBackground:YES ];

是否有網路請求:

[ ASIHTTPRequest isNetworkInUse ]

是否顯示網路請求資訊在status bar上:

[ ASIHTTPRequest setShouldUpdateNetworkActivityIndicator:NO ];

佈建要求逾時時,設定重試的次數:

[ 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 ];

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.