ASIHttpRequest使用詳解

清風颺發表於2016-05-23

轉載:http://www.cnblogs.com/pengyingh/articles/2343062.html

ASIHTTPRequest就是一個對CFNetwork API進行了封裝,並且使用起來非常簡單的一套API,用Objective-C編寫,可以很好的應用在Mac OS X系統和iOS平臺的應用程式中。ASIHTTPRequest適用於基本的HTTP請求,和基於REST的服務之間的互動

  • l 通過簡單的介面,即可完成向服務端提交資料和從服務端獲取資料的工作
  • l 下載的資料,可儲存到記憶體中或直接儲存到磁碟中
  • l 能上傳本地檔案到服務端
  • l 可以方便的訪問和操作請求和返回的Http頭資訊
  • l 可以獲取到上傳或下載的進度資訊,為應用程式提供更好的體驗
ASIHTTPRequest是一款極其強勁的HTTP訪問開源專案。讓簡單的API完成複雜的功能,

  • 目錄

  • 發起一個同步請求

  • 建立一個非同步請求

  • 佇列請求

  • 請求佇列上下文

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

  • 取消非同步請求

  • 安全的記憶體回收建議

  • 向伺服器端上傳資料

  • 下載檔案

  • 獲取響應資訊

  • 獲取請求進度

  • cookie的支援

  • 大檔案斷點續傳

  • ASIDownloadCache 設定下載快取

  • 多種的快取並存

  • 快取策略

  • 快取儲存方式

  • 快取其它特性

  • 實現自定義的快取

  • 使用代理請求

  • 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 = [ASIHTTPRequestrequestWithURL:url];
    [request startSynchronous];NSError *error = [request error];if (!error) {
    NSString *response = [request responseString];}
}

a,requestWithURL快捷方法獲取ASIHTTPRequest的一個例項
b, startSynchronous方法啟動同步訪問,
c,由於是同步請求,沒有基於事件的回撥方法,所以從requesterror屬性獲取錯誤資訊。
d, responseString,為請求的返回NSString資訊。


二,發起一個非同步請求
非同步請求的好處是不阻塞當前執行緒,但相對於同步請求略為複雜,至少要新增兩個回撥方法來獲取非同步事件。下面非同步請求程式碼完成上面同樣的一件事情:

- (IBAction)grabURLInBackground:(id)sender
{
    NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
    ASIHTTPRequest *request = [ASIHTTPRequestrequestWithURL:url];
    [request setDelegate:self];
    [request startAsynchronous];
}
-  (void)requestFinished:(ASIHTTPRequest *)request{
// Use when fetching text data
    NSString *responseString = [request responseString];
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 = [ASIHTTPRequestrequestWithURL:url];
[request setDelegate:self];
[request setDidFinishSelector:@selector(requestDone:)];
[request setDidFailSelector:@selector(requestWentWrong:)];
[[self queue] addOperation:request]; //queue is anNSOperationQueue
}
-(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中,當請求響應完可以通過訪問requestuserInfo獲取裡面的資訊

b,為一個請求例項設定不同的setDidFinishSelector / setDidFailSelector

的回撥方法
c,子類化ASIHTTPRequest,重寫requestFinished:failWithProblem:方法


五,ASINetworkQueues delegate提供的更多的回撥方法如下

:a,requestDidStartSelector,請求發起時會調此方法,可以在此方法中跟據選擇性的設定requestdelegate

b,requestDidReceiveResponseHeadersSelector,當接完響應的Header設計此方法,這個對下載大資料的時相當有用,可以在方法裡更多務上的處理。

c,requestDidFinishSelector,請求並響應成功完成時呼叫此方法

d,requestDidFailSelector,請求失敗

e,queueDidFinishSelector,個佇列裡的所有請求都結束時呼叫此方法。

它是NSOperationQueues擴充套件,而強大。但與它的父類略有區別。如,新增到佇列中其實並不能執行請求,有呼叫[ queue g o]執行;一個執行中的佇列,並不復呼叫[ queue go ]


認情下,佇列中的一個請求如失敗,它會取消所有完成的請求。可以設定[ queuesetShouldCancelAllRequestsOnFailure:NO ]修 正


六,取消非同步請求

首先,同步請求是不能取消的。其,不是佇列請求,還是簡單的非同步請求,全部呼叫[ request cancel ]來取消請求。

取消的請求請求失敗處理,並呼叫請求失敗delegate

呼叫delegate方法,設定:[ request clearDelegatesAndCancel];佇列請求中意的是,如果你取消了一個請求,佇列會自動取消其它所有請求。
果只想取消一個請求,可以設定佇列:[ queuesetShouldCancelAllRequestsOnFailure:NO ];

果想取消所有請求:[ queue cancelAllOperations ];


七,安全的記憶體回收建議

request並沒有retaindelegate,所以在沒有請求完的時候釋放了此delegate,要在dealloc方法裡取消所有請求,再釋放請求例項,如:

- (void)dealloc
{
[request clearDelegatesAndCancel];[request release];
...
[super dealloc];
}

八,向服務端上傳資料

ASIFormDataRequest,模擬Form單提,其提交格式與Header會自動識別
沒有檔案:
application/x-www-form-urlencoded有檔案:multipart/form-data

<span style="font-size:18px;">ASIFormDataRequest *request = [ASIFormDataRequestrequestWithURL: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 = [ASIHTTPRequestrequestWithURL:url];
[request appendPostData:[@"This is my data"dataUsingEncoding:NSUTF8StringEncoding]];
// Default becomes POST when you use appendPostData: /appendPostDataFromFile: / setPostBody:
[request setRequestMethod:@"PUT"];</span>

九,下載檔案

通過設定requestsetDownloadDestinationPath,可以設定下載檔案用的下

載目目錄。首先,下載程檔案會存在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,可以獲取上傳進度

10,cookie

cookieCookie存在的,會資訊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:[NSDatedateWithTimeIntervalSinceNow: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:[NSMutableArrayarrayWithObject: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 設定下載快取

ASIDownloadCache它對Get請求的響應資料進快取(被快取的資料必需是成功的200請求):

[ASIHTTPRequest setDefaultCache:[ASIDownloadCachesharedCache]];當設定快取策略,所有的請求被自動的快取起來。另外,如果僅僅希望某次請求使用快取操作,可以這樣使用:ASIHTTPRequest *request = [ASIHTTPRequestrequestWithURL:url];

[request setDownloadCache:[ASIDownloadCachesharedCache]];
僅僅需要建立不同的ASIDownloadCache,並設定快取所使用的路徑,並設定到要使用的request例項中:

ASIDownloadCache *cache = [[[ASIDownloadCache alloc]init] autorelease];
[cache setStoragePath:@"/Users/ben/Documents/Cached-Downloads"];

[self setMyCache:cache];
ASIHTTPRequest *request = [ASIHTTPRequestrequestWithURL:url];
[request setDownloadCache:[self myCache]];

十三,快取策略
快取策略是我們控制快取為的主要方式,如:什麼快取,快取資料的用方式。
以下是策略可
(可組合使用):

ASIUseDefaultCachePolicy

ASIDoNotReadFromCacheCachePolicy

這是一個認的快取策略“ASIAskServerIfModifiedWhenStaleCachePolicy”,這個,見名知意(它不能與其它策略組合使用)

資料不使用快取ASIDoNotWriteToCacheCachePolicy不對快取資料進行寫操作

認快取為,request先判斷是存在快取資料。

a,沒有網路請求。

b,如存在快取資料,並資料沒有過,ASIAskServerIfModifiedWhenStaleC,使用快取。

c,如存在快取資料,achePolicy已經過期,request網路請求,

斷伺服器版本與本地版本是一樣,如 一樣,使用快取。如伺服器有新版本,

能與其它策略組合使用)

ASIDoNotReadFromCacheCachePolicy

資料不使用快取ASIDoNotWriteToCacheCachePolicy不對快取資料進行寫操作

ASIAskServerIfModifiedWhenStaleCachePolicy

ASIAskServerIfModifiedCachePolicyASIOnlyLoadIfNotCachedCachePolicy

ASIDontLoadCachePolicy

ASIFallbackToCacheIfLoadFailsCachePolicy

認快取為,request先判斷是存在快取資料。

a,沒有網路請求。

b,如存在快取資料,並資料沒有過期,使用快取。

c,如存在快取資料,但已經過期,request網路請求,斷伺服器版本與本地版本是一樣,如一樣,使用快取。

伺服器有新版本,會進網路請求,並更新本地快取與認快取大一樣,區別僅每次請求伺服器斷是有更新

有快取在本地,不過期,

來使用

當有快取的時候才會被正確執行,如沒有快取,request將被取消(沒有錯誤資訊)這個經常被用來與其它組合使用。請求失敗時,如有快取當網路返回本地快取資訊(這個在處理異非常有用)

設定了“defaultCachePolicy”所有的請求會使用此快取。

可以設定快取的資料存多,ASIHTTPRequest提供了兩種策略:

a,ASICacheForSessionDurationCacheStoragePolicy,認策略,基於session的快取資料儲存。

當下次執行[ASIHTTPRequest clearSession]時,快取將失

b,ASICachePermanentlyCacheStoragePolicy,快取資料永久保存在本地,

如:

ASIHTTPRequest *request = [ ASIHTTPRequestrequestWithURL:url ];
[ request

setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy ];

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

設定是否按伺服器在Header裡指定的是可被快取或過期策略進快取:

[[ ASIDownloadCache sharedCache ]setShouldRespectCacheControlHeaders:NO ];設定request快取的有:

[ request setSecondsToCache:60*60*24*30 ]; //快取30可以斷資料是從快取取:
[ request didUseCachedResponse ];
設定快取所使用的路徑:

[ request setDownloadDestinationPath:[[ ASIDownloadCachesharedCache ]pathToStoreCachedResponseDataForRequest:request ]];要簡單的實現ASICacheDelegate就可以被用來使用。

十四,使用代理請求

認的情下,ASIHTTPRequest會使用被設定的認代理。但你也可以修改http代理:
// Configure a proxy server manually
NSURL *url = [ NSURL URLWithString:@"http://allseeing-i.com/ignore" ];

ASIHTTPRequest *request = [ ASIHTTPRequestrequestWithURL:url ];
[ request setProxyHost:@"192.168.0.1" ];[ request setProxyPort:3128 ];

// Alternatively, you can use a manually-specified ProxyAuto 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中,當應用後臺執行仍然請求資料:
[ requestsetShouldContinueWhenAppEntersBackground:YES ];有網路請求:
[ ASIHTTPRequest isNetworkInUse ]否顯示網路請求資訊在status bar上:
[ ASIHTTPRequestsetShouldUpdateNetworkActivityIndicator:NO ];設定請求時時,設定重試數:
[ request setNumberOfTimesToRetryOnTimeout:2 ];

KeepAlive的支援:
// Set the amount of time to hang on to a persistentconnection before it should expire to 2 minutes
[ request setPersistentConnectionTimeoutSeconds:120 ];

// Disable persistent connections entirely
[ request setShouldAttemptPersistentConnection:NO ];

... other posts bypimacun 

參考來源:

官方文件

https://allseeing-i.com/ASIHTTPRequest

相關文章