http://qk13warcraft.blog.163.com/blog/static/157549344201271633014969/
一、建立和运行请求
建立一个同步请求
这是最简单的用法,发送 startSynchronous 消息将在相同线程中执行请求,无论是否成功,完成后返回控制。
查看error属性以检测问题。
要以字符串形式获得响应,就调用responseString方法。这个方法不适合二进制数据 - 你应该使用responseData 获得NSData对象,或者若是有更大的文件,你能够设置downloadDestinationPath将请求下载到文件。
- (IBAction)grabURL:(id)sender { ios
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"]; git
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; github
[request startSynchronous]; web
NSError *error = [request error]; apache
if (!error) { json
NSString *response = [request responseString]; windows
} api
}浏览器
注意:通常的,你应该优先使用异步请求,若是你在主线程中使用ASIHTTPRequest的同步方法,程序的ui在请求过程当中将被锁定而没法响应。
二、建立一个异步请求
下面的代码作一样的事情,但请求运行于后台。
- (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];
}
注意咱们设置请求的委托,这样就能在请求完成或失败时获得通知。
这是建立异步请求最简单的方式,他会运行于场景后面的一个全局的NSOperationQueue中,对于更复杂的操做,例如在多个请求中追踪进展,你可能想要建立本身的队列,下面咱们谈谈这个。
三、使用程序块(blocks)
对于v1.8,咱们能够在支持程序块的平台使用他们:
- (IBAction)grabURLInBackground:(id)sender {
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
__block ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setCompletionBlock:^{
// Use when fetching text data
NSString *responseString = [request responseString];
// Use when fetching binary data
NSData *responseData = [request responseData];
}];
[request setFailedBlock:^{
NSError *error = [request error];
}];
[request startAsynchronous];
}
注意:在咱们声明请求时,用到了__block限定语,这很重要!它告诉block不要保留请求,来防止一个保留循环(retain-cycle),由于请求总会保留block.
四、使用队列
这个例子作一样的事,不一样的是,咱们为本身的请求建立了NSOperationQueue。
使用一个NSOperationQueue或者ASINetworkQueue,你能更有效的控制异步请求。咱们使用一个请求,只有必定数量的请求能同时 运行。若是你添加多于maxConcurrentOperationCount数量的请求,这些请求将等到其余请求完成后才会开始。
- (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];
}
在上面的例子中,'queue'是控制器的一个保留的NSOperationQueue属性。
咱们设置自定义的selector处理成功或失败的回调。若是你不设置这些,默认的requestFinished和requestFailed将被使用,就像在以前的例子中同样。
在委托方法中处理对歌请求的成功和失败
若是你须要处理许多不一样类型的请求,你有几个选择:
1. 若是你的请求都属于一个大的范围,你又想区别他们,能够设置请求的userInfo字典属性,填入你的自定义数据,你就能够在委托方法中读取了。在更简单的用例中,你能够简单的设置tag属性。这些属性都是给你本身用的,不会发送到服务器。
2. 若是你处理彻底不一样的请求,为每一个请求设置不一样的 setDidFinishSelector / setDidFailSelector。
3. 对更复杂的状况,或者你想在后台解析响应数据,能够为每一个请求类型建立一个ASIHTTPRequest的子类,而后重载requestFinished: 和 failWithError: 。
注意:最好避免在委托方法中,用url来区分不一样的请求,由于url属性在重定向时会改变。若是你真的真的想用的话,请用[request originalURL] 代替,这个将老是记录第请求链接时的首个url。
五、关于ASINetworkQueues
ASINetworkQueues是NSOperationQueue,它提供了额外的功能。
它的主要目的是追踪整个队列上传或下载的进度。
ASINetworkQueues提供了一些额外的委托方法selector。
requestDidStartSelector
每当队列中的一个请求开始运行时调用。你可使用这个做为didStartSelector的替代方法,为你加到队列的请求设置一个委托。
requestDidReceiveResponseHeadersSelector
每当队列中的一个请求从服务器获得响应头时调用。对于大的下载,这个 selector有时在请求实际完成前执行。
你可使用它做为对didReceiveResponseHeadersSelector的替代。
requestDidFinishSelector
每当队列中的一个请求完成时调用。可使用它做为对didFinishSelector的替代。
requestDidFailSelector
每当队列中的请求失败时调用,可做为didFailSelector的替代。
queueDidFinishSelector
当队列完成时调用,无论单个请求成功或失败。
使用以上selector,要将队列的委托,而不是请求的委托,设置到实现这些selector所表明的方法的控制器。
ASINetworkQueues工做起来和NSOperationQueues稍有不一样,加到其中的请求不会马上运行,当使用 ASINetworkQueue时,添加你想运行的全部请求,而后调用[queue go]。当你启动一个队列,将精确进度(accurate progress)打开时,他会首先为队列中全部的get请求执行一个head请求,来获得将要下载数据的整体尺寸。得到此数据后,它就能准确的显示整体 进度,而后真实的请求才会开始。
问题:当你向一个运行中的ASINetworkQueue加入一个请求时发生了什么事情?
回答:若是你使用ASINetworkQueue来追踪几个请求的整体进度,总体进度只会在哪一个请求开始执行时,才会将它计算在内。 ASINetworkQueue不会在运行中,当加入请求后执行head请求,因此若是你马上向运行的队列加入许多请求,整体进度不会马上更新。
若是队列已经运行,你不须要再次调用[queue go]。
当ASINetworkQueue中的一个请求失败,队列默认的将取消全部其余的请求。你能够调用[queue setShouldCancelAllRequestsOnFailure:NO].来关闭这一行为。
ASINetworkQueues只能执行ASIHTTPRequest操做,而不能用于通常操做,尝试添加一个非ASIHTTPRequest的NSOperation将产生一个异常。
提示:这里有一个建立和使用ASINetworkQueue的完整例子:
http://gist.github.com/150447
六、取消一个异步请求
为了取消一个异步请求,能够调用[request cancel],无论该请求是用[request startAsynchronous] 启动的,仍是在你建立的队列中运行。注意你不能取消一个同步请求。
注意,当你取消一个请求,请求会将之视为一个错误,而后会调用你的委托或者队列的失败委托方法。若是你不想这种事发生,在取消以前将委托设为nil,或者使用clearDelegatesAndCancel做为代替。
// Cancels an asynchronous request
[request cancel] // Cancels an asynchronous request, clearing all delegates and blocks first
[request clearDelegatesAndCancel];
当使用一个ASINetworkQueue时,你取消其中一个请求,全部其余的请求也会被取消,除非队列的shouldCancelAllRequestsOnFailure为no, 默认为yes。
// When a request in this queue fails or is cancelled, other requests will continue to run
[queue setShouldCancelAllRequestsOnFailure:NO];
// Cancel all requests in a queue
[queue cancelAllOperations];
七、
安全处理委托在请求完成前释放的状况
请求不会保留他们的委托,因此若是你的委托有机会在请求运行时释放的话,你能及时清理请求的委托属性是相当重要的。在大多数状况下,若是你的委托将要释放,你大概也想取消请求,由于你再也不关心请求的状态。
在下面的例子中,控制器有一个保存于保留实例变量中的ASIHTTPRequest对象。咱们在其dealloc实现中调用clearDelegatesAndCancel方法,在咱们释放请求的引用以前:
// Ddealloc method for our controller
- (void)dealloc {
[request clearDelegatesAndCancel];
[request release];
..
[super dealloc];
}
八、发送数据
发送请求头
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request addRequestHeader:@"Referer" value:@"http://allseeing-i.com/"];
用ASIFormDataRequest发送一个表单
要以兼容web页表单的方式发送post数据,可使用ASIFormDataRequest的子类。数据以‘application/x-www- form-urlencoded’格式寄出,或者用‘multipart/form-data’格式上传二进制数据或文件。文件中的数据按照须要从磁盘读 取,因此发送大文件是没问题的,只要你的web服务器设置了如何处理他们。
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"];
ASIFormDataRequest使用setFile:forKey:添加文件时将自动侦测文件的mime类型(ios3.0以后),并包含这个到发送到服务器的mime头部中。若是你愿意,你可使用更长的重载形式:
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
// Upload a file on disk
[request setFile:@"/Users/ben/Desktop/ben.jpg" withFileName:@"myphoto.jpg" andContentType:@"image/jpeg"
forKey:@"photo"];
// Upload an NSData instance
[request setData:imageData withFileName:@"myphoto.jpg" andContentType:@"image/jpeg" forKey:@"photo"];
你能够为同一个参数发送多个值使用其余的add api:
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request addPostValue:@"Ben" forKey:@"names"];
[request addPostValue:@"George" forKey:@"names"];
[request addFile:@"/Users/ben/Desktop/ben.jpg" forKey:@"photos"];
[request addData:imageData withFileName:@"george.jpg" andContentType:@"image/jpeg" forKey:@"photos"];
参考ASIFormDataRequest.h,了解添加到你post的参数的全部方法的完整列表。
九、put方法和自定义post
若是你想经过put发送数据,或者想要发送post,可是想本身建立post数据体(body),使用appendPostData: 或者 appendPostDataFromFile:。
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"];
若是你想发送大量的数据,而且不用ASIFormDataRequest,参看后面的‘从磁盘以流式post数据’小节。
十、下载数据
将响应数据直接下载为文件
若是你请求的数据至关大,你能够直接将下载内存直接保存为文件。这样,ASIHTTPRequest不须要一次在内存中保存整个请求。
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadDestinationPath:@"/Users/ben/Desktop/my_file.txt"];
当使用downloadDestinationPath下载到文件时,下载过程当中,数据将被保存在一个临时文件中。这个文件路径保存于temporaryFileDownloadPath。当请求成功完成,下面的事情之一会发生:
若是数据时gzip压缩过的,压缩文件将被解压到downloadDestinationPath,而且临时文件被删除;
若是数据没被压缩,临时文件移动到downloadDestinationPath,覆盖掉任何以前的文件。
注意:若是响应body是空的,文件是不会被建立的。因此若是请求可能返回一个空的body,你要肯定在尝试操做文件以前,检查它是否存在
十一、处理收到的响应数据
若是你须要处理收到的响应数据,好比你想使用流解析器(streaming parser)来解析仍在下载的响应数据,就须要在委托中实现request:didReceiveData:方法。注意当你这么作 时,ASIHTTPRequest不会产生responseData,也不会将数据写入downloadDestinationPath - 你必须本身搞定保存响应数据的事。
读取HTTP状态码
ASIHTTPRequest 不会鸟大多数的http状态码,重定向和验证的状态码除外。因此,就要靠你检查问题,好比404错误,而后肯定你作了恰当的处理。
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request startSynchronous];
int statusCode = [request responseStatusCode];
NSString *statusMessage = [request responseStatusMessage];
读取响应头
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request startSynchronous];
NSString *poweredBy = [[request responseHeaders] objectForKey:@"X-Powered-By"];
NSString *contentType = [[request responseHeaders] objectForKey:@"Content-Type"];
处理文本编码
ASIHTTPRequest会尝试从Content-Type头获得数据的编码。若是它发现了一个编码类型,他会社子responseEncoding 为相应的NSStringEncoding。若是它没在头部发现编码信息,就会用defaultResponseEncoding,这个值默认为 NSISOLatin1StringEncoding。
当你调用[request responseString],ASIHTTPRequest将尝试用responseEncoding做为源编码,从收到的数据建立一个字符串。
处理重定向
当ASIHTTPRequest碰到如下http状态码时,会自动重定向到一个新的url,假设Location头已经发送:
301 永久移动
302 发现
303 参看其余
当重定向发生,响应数据(responseHeaders / responseCookies / responseData / responseString 等) 的值将反映从最终位置收到的内容。
在重定向周期中碰到的任何url上设置的Cookie,都倍存储到全局cookie仓库,在恰当的时候会由重定向请求呈现给服务器。
你能够关闭自动重定向,设置shouldRedirect属性为no便可。
注意:默认状况下,自动重定向老是以get方式进行请求(没有body)。这个行为复合大多数的浏览器,除了象301和302这样应该用原有方式重定向的规范。
为了保留301和302的原有方式(包含请求的body),须要将shouldUseRFC2616RedirectBehaviour设置为yes,在你开始请求以前。
十二、跟踪进度
每一个ASIHTTPRequest都有两个用于跟踪进度的委托 - downloadProgressDelegate用于下载,uploadProgressDelegate用于上传。
进度委托能够是NSProgressIndicators(Mac OS X)或者UIProgressViews(iPhone)。ASIHTTPRequest会自动适应这二者行为上的差别。你也可以使用自定义的类做为进度 委托,只要它响应setProgress:方法。
若是你正执行单个请求,在这个请求上设置一个上传或下载委托。
若是你在队列中执行多个请求,而且想跟踪队列中全部请求的整体进度,可使用ASINetworkQueue并设置队列的进度委托
若是想同时作上面两件事,也是可行的。
重点注意:若是你正在向须要验证的站点进行上传操做,为了提供有效验证,每当上传失败时,进度会被重设为以前的值。为此,若是你正同验证web服务器通 信,建议你仅当useSessionPersistence为yes时使用上传进度委托,并确保你在尝试跟踪大量上传数据前,在另外一个请求中验证。
当请求body小于128kb时,目前是不可以跟踪上传进度的。对请求大于128kb的请求,进度委托不会收到第一个128kb的post数据进度的信息。这是由于CFNetwork API的限制形成的。
2009.6.21日更新:apple的好家伙很是友好的定位了个人bug报告!在iphone 2.0 sdk中,貌似这个缓冲尺寸减少到了32kb,这让精确的上传进度跟踪更加可靠了。
1三、跟踪单个请求的下载进度
在这个例子中,myProgressIndicator是一个NSProgressIndicator。
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadProgressDelegate:myProgressIndicator];
[request startSynchronous];
NSLog(@"Max: %f, Value: %f", [myProgressIndicator maxValue],[myProgressIndicator doubleValue]);
跟踪一组请求的下载进度
这个例子中,myProgressIndicator 是一个UIProgressView,myQueue是一个ASINetworkQueue。
- (void)fetchThisURLFiveTimes:(NSURL *)url
{
[myQueue cancelAllOperations];
[myQueue setDownloadProgressDelegate:myProgressIndicator];
[myQueue setDelegate:self];
[myQueue setRequestDidFinishSelector:@selector(queueComplete:)];
int i;
for (i=0; i<5; i++) {
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[myQueue addOperation:request];
}
[myQueue go];
}
- (void)queueComplete:(ASINetworkQueue *)queue
{
NSLog(@"Value: %f", [myProgressIndicator progress]);
}
注意对于ASINetworkQueues,咱们必须调用[myQueue go]来启动队列。
跟踪单个请求的上传进度
本例中,myProgressIndicator是一个UIProgressView。
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:@"Ben" forKey:@"first_name"];
[request setPostValue:@"Copsey" forKey:@"last_name"];
[request setUploadProgressDelegate:myProgressIndicator];
[request startSynchronous];
NSLog(@"Value: %f",[myProgressIndicator progress]);
跟踪一组请求的上传进度
本例中,myProgressIndicator是一个NSProgressUbdicator,myQueue是一个ASINetworkQueue。
- (void)uploadSomethingFiveTimes:(NSURL *)url
{
[myQueue cancelAllOperations];
[myQueue setUploadProgressDelegate:myProgressIndicator];
[myQueue setDelegate:self];
[myQueue setRequestDidFinishSelector:@selector(queueComplete:)];
int i;
for (i=0; i<5; i++) {
ASIHTTPRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostBody:[@"Some data" dataUsingEncoding:NSUTF8StringEncoding]];
[myQueue addOperation:request];
}
[myQueue go];
}
- (void)queueComplete:(ASINetworkQueue *)queue
{
NSLog(@"Max: %f, Value: %f", [myProgressIndicator maxValue],[myProgressIndicator doubleValue]);
}
1四、
精确进度vs简单进度
ASIHTTPRequest提供了两种显示进度的途径,简单进度 和 精确进度。他们由ASIHTTPRequests 和 ASINetworkQueues的showAccurateProgress来控制。若是你在一个请求上设置 showAccurateProgress,只会影响这个请求。若是你设置了队列,将影响到队列的所有请求。
简单请求
当你使用简单进度,进度仅在请求完成时更新。对于单个进程,你只能获得0%和100%完成。对于一个包括4个请求的队列,你能获得5次进度更新,0%,25%,50%,75%和100%,每一次增量代表有一个请求完成了。
简单进度(showAccurateProgress = NO)是ASINetworkQueues的默认值,它很好的适用于包含大量的轻量级上传/下载请求的队列。
精确进度
使用精确进度时,进度以收发的字节来更新,因此极适合收发大量数据的请求,它会更好的指示一个耗时请求收发了多少数据。
使用精确进度会稍稍下降上传操做的性能,由于进度委托(多是UIProgressView或者NSProgressIndicator)将更为频繁的重绘。
使用精确进度会对使用队列的下载任务影响更大,由于队列在下载前,会先为其中的get请求执行head请求,来决定将要下载的数据整体尺寸。强烈推荐你在队列中下载大文件时使用精确进度,可是应该避免队列中包含大量小型下载时使用它。
精确进度(showAccurateProgress = YES)是ASIHTTPRequests执行同步任务时的默认值。
1五、
自定义进度跟踪
ASIProgressDelegate协议定义了获得请求的更新进度的委托的全部方法。大多数状况下,为NSProgressIndicator或 UIProgressView设置uploadProgressDelegate 或 downloadProgressDelegate就足够了。可是,若是你想作更复杂的进度跟踪,你的进度委托应该优先于setProgress: (iOS) 或者setDoubleValue: / setsos5403: (Mac)实现下列方法。这些方法容许你获得收发的实际字节数,而不是更简单的方法获得的介于0和1之间的数字。
downloadProgressDelegates的方法
request:didReceiveBytes:每当请求下载更多数据时在downloadProgressDelegate上调用。注意这有别于通常会实现的request:didReceiveData:委托。
request:incrementDownloadSizeBy:下载尺寸改变时被调用,传入的参数是下载尺寸的增量。通常发生在请求收到响应头并得到了下载的尺寸时。
uploadProgressDelegates的方法
request:didSendBytes: 每当请求能发送一些数据时在uploadProgressDelegate上调用。重点提醒:这个方法能被小于0的数字调用,当一个请求须要删除上传进度 时(通常是当它已经上传了数据,可是验证失败或者因为某种缘由须要再次运行时)。
request:incrementUploadSizeBy: 上传尺寸改变时调用。传入的尺寸常常会小于0,因为请求调整了上传尺寸,它将os内部的缓冲尺寸也计算在内了。
1六、
处理http验证
若是你正在链接到须要验证的服务器,你大概想要看看这个流程图
http://allseeing-i.com/ASIHTTPRe ... ticationProcess.pdf
,演示了ASIHTTPRequest如何找到和应用请求验证。
在url中指定用户名和密码
NSURL *url = [NSURL URLWithString:@"http://username:password@allseeing-i.com/top_secret/"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
设置请求的用户名和密码
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/top_secret/"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setUsername:@"username"];
[request setPassword:@"password"];
1七、
在键链(keychain)中储存证书
若是你打开了keychainPersistence,任何你提供的有效用户名和密码将被存储到键链中。随后的请求会重用键链中的用户名和密码,即便你退出再重启应用。
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/top_secret/"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setUseKeychainPersistence:YES];
[request setUsername:@"username"];
[request setPassword:@"password"];
若是你使用键链同时但愿本身管理它,你应该能在ASIHTTPRequest.h中找到有助于此与键链相关的类方法。
1八、
在会话中保存证书
若是useSessionPersistence打开了,默认是打开的,ASIHTTPRequest将证书保存到内存,并能够在后续请求中重用他们。
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/top_secret/"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setUsername:@"username"];
[request setPassword:@"password"];
[request setUseSessionPersistence:YES]; //Shouldn't be needed as this is the default
//Should reuse our username and password
request = [ASIHTTPRequest requestWithURL:url];
1九、NTML验证
要经过使用ntml方案的windows服务器进行验证,你还须要指定你验证的域(domain)。
NSURL *url = [NSURL URLWithString:@"http://my.windows.server/top_secret/"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setUsername:@"username"];
[request setPassword:@"password"];
[request setDomain:@"my-domain"];
使用委托来提供证书
相对于提早指定验证证书,你可能更愿意在请求不能从会话验证缓存或键链中获得证书时,向它的委托询问。这可能有助于你但愿连到一个服务器,但你不肯定它须要哪一种类型的验证。
肯定你的委托实现了authenticationNeededForRequest,ASIHTTPRequest会暂停一个请求,当它等待一个委托以获 得将要使用的证书时。当你有你须要的证书时,只要在请求上设置他们,而后调用[request retryUsingSuppliedCredentials],若是你想取消,就要调用[request cancelAuthentication],这也会取消请求。
对于v1.0.8,请求的委托一次只会收到一个authenticationNeededForRequest或者 proxyAuthenticationNeededForRequest。当委托处理第一个请求时,其余须要验证的请求会暂停执行。若是证书经过验证, 任何当前进程的其余请求都会尝试重用他们,假设他们对url有效。若是委托取消了验证,且队列的 shouldCancelAllRequestsOnFailure为yes,全部其余的请求再也不尝试查询证书而会取消。
在使用同步请求时,你不能使用代理模式进行验证。
在老版本中这会致使应用挂起,对于v1.0.8代理方法再也不被调用。
20、使用内置验证对话框(目前仅ios可用)
在v1.0.8中新增了ASIAuthenticationDialog类。它主要用来和验证代理一同工做,可是它能够被用来为验证web服务器询问用户的证书。
为了最好的用户体验,多数连到单个服务的应用应该在其委托中实现authenticationNeededForRequest:,或者避免彻底的使用委 托样式(delegate-style)验证。可是有时为常规验证而使用ASIHTTPRequest的标准验证对话框有些好处:
你不想建立你本身的登陆表单
你大概须要从外部来源得到数据,而不太肯定它需不须要验证。
为此,在请求中设置shouldPresentAuthenticationDialog为true,若是你的委托没有实现authenticationNeededForRequest,用户将看到此对话框。
验证对话框不会在同步请求时出现。
对话框有点模仿了iphone上的safari,并包括:
一条消息指明这个认证是为web服务器作的(而不是代理)
你链接到的服务器的主机名或ip
验证域(authentication realm),若是支持的话
输入用户名和密码的文本框
当链接到一个使用ntlm方案的服务器时,对话框也包括一个输入域(domain)的文本框
关于验证是否以明文(plain text)发送的提示(仅在用无ssl的基本验证时才被明文发送)。
若是你想改变对话框的外观,子类化ASIHTTPRequest,重载showAuthenticationDialog来显示你本身的自定义对话框或者子类化ASIAuthenticationDialog。
2一、在服务器要求以前提供证书
很是重要:在v1.0.8中,使用基本验证的请求时,这个特征改变了,你可能须要更新你的代码。
ASIHTTPRequest能够在首次请求时就为服务器提供证书,而不是等到服务器要求证书。结果是使用验证时得到更好的性能,由于它避免了额外的请求。
使用基本验证来触发此行为时,你应该手动设置请求的authenticationScheme:
[request setAuthenticationScheme:(NSString *)kCFHTTPAuthenticationSchemeBasic];
使用其余验证方案时,证书能够在服务器要求以前提供,但只有在另外一个请求成功经过此服务器验证以后。
你可能但愿禁用此特征,若是:
你的应用可能使用多组证书来同时和同一个服务器对话。
你的应用是安全至上的,使用这个特性自己不太安全,由于在你有机会验证你链接到你但愿链接的服务器以前,证书已经被发送了。
为了禁用此特征,使用如下代码:
[request setShouldPresentCredentialsBeforeChallenge:NO];
2二、Cookies
持久化cookies
ASIHTTPRequest容许你使用全局存储,全局存储为全部max os上使用CFNetwork或NSURLRequest API的应用所共享。若是useCookiePersistence为on(默认如此),cookies将被保存到共享的 NSHTTPCookieStorage容器中,并自动被其余请求自动重用。若是cookie仅对特定请求有效,ASIHTTPRequest提供其余程 序建立的cookie是没有价值的。
你能够象这样清除在会话中建立的全部cookie:
[ASIHTTPRequest setSessionCookies:nil];
这里,'会话cookie'指的一个会话中建立的全部cookie,而不是程序退出时被删除的无过时时间的cookie(常常被称为会话cookie)。
另外,类的方便(convenience)方法clearSession将清除全部会话中建立的cookie,以及任何缓存的验证数据。
手工处理cookie
若是你喜欢,你能够关掉useCookiePersistence,而后手动管理特定请求的一组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:[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' cookie
url = [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]);
2三、处理压缩的响应,以及压缩请求body
使用gzip来处理压缩的响应数据
对于v0.9,ASIHTTPRequest不会提醒服务器它能够接受gzip压缩格式数据。若是你在现有项目中升级ASIHTTPRequest,参看设置指令地址
http://allseeing-i.com/ASIHTTPRequest/Setup-instructions
了解如何连接到zlib。
许多web服务器能够在发送数据前进行压缩 - 这样能够加快下载和下降使用带宽,代价是服务器(用以压缩数据)和客户端(解压数据)增长了额外的cpu时间。通常说来,只有某些类型的数据会被压缩 - 许多二进制格式例如jpeg,gif,png,swf和pdf已经压缩过他们的数据,因此gzip压缩不会用于发送他们到客户端。文本文件如网页和xml 文档是gzip压缩的完美候选人,由于他们常常包含大量重复信息。
如何设置apache使用mod_deflate来压缩数据
apatche 2.x 以后带来了mod_deflate扩展容许透明的压缩某些类型的数据。要打开他,你须要在apatche配置文件中启用mode_deflate,并添加mod_deflate指令到你的虚拟主机配置中,或者到你的.htaccess文件中。
在ASIHTTPRequest中使用gzip
- (IBAction)grabURL:(id)sender
{
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
// YES is the default, you can turn off gzip compression by setting this to NO
[request setAllowCompressedResponse:YES];
[request startSynchronous];
BOOL *dataWasCompressed = [request isResponseCompressed]; // Was the response gzip compressed?
NSData *compressedResponse = [request rawResponseData]; // Compressed data
NSData *uncompressedData = [request responseData]; // Uncompressed data
NSString *response = [request responseString]; // Uncompressed data as a string
}
当allowCompressedResponse为真,ASIHTTPRequest将添加Accept-Encoding头到请求中,代表咱们能够接 受gzip压缩的响应数据。若是响应头包含一个content-encoding头指明了数据已被压缩,调用responseData 或者 responseString将在返回前解压数据。你能够经过调用rawResponseData获得原始压缩数据。
联机解压gzip响应包
默认的,ASIHTTPRequest会一直等到请求完成对gzip响应包的解压缩。设置 shouldWaitToInflateCompressedResponses属性为no,你能够告诉ASIHTTPRequest在收到数据同时进行 解压。有时候,这会提高一点速度,由于当一个请求等待更多响应时,数据能够同时被处理。
这个特性对于须要使用流解析器(streaming parser)如xml或json解析器时尤为有用,打开这个选项,你能够直接给你的解析器输送解压过的数据,他们来自你委托实现的request:didReceiveData: 方法。
注意当shouldWaitToInflateCompressedResponses为no时,原始(压缩过的)数据将被丢弃,参看ASIHTTPRequest.h的注释得到更多信息。
使用gzip来压缩请求body
v1.0.3新增了请求body的gzip压缩。使用这个特性,你的应用能够压缩post/put操做的内容,只要设置shouldCompressRequestBody为yes便可。shouldCompressRequestBody默认为no。
当你配置了SetInputFilter DEFLATE 后,apatche的mod_deflate能够自动的解压gzip请求体。这个方法为cgi内容工做,可是若是你使用apatche模块构建成了一个 RESOURCE过滤器(如mod PHP)则不能工做,这时你须要本身搞定数据解压。
注意:ASIHTTPRequest不能检查到服务器是否接受gzip请求体。只有当你肯定服务器能搞定gzip body时使用这项特性。
避免对压缩格式文件如jpeg/png/gif/pdf/swf使用gzip,你会发现gzip版本会比原始文件大。
2四、恢复被打断的下载
自v0.94开始,ASIHTTPRequest可以恢复不完整的下载
- (IBAction)resumeInterruptedDownload:(id)sender
{
NSURL *url = [NSURL URLWithString:
@"http://allseeing-i.com/ASIHTTPRequest/Tests/the_great_american_novel.txt"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
NSString *downloadPath = @"/Users/ben/Desktop/my_work_in_progress.txt";
// The full file will be moved here if and when the request completes successfully
[request setDownloadDestinationPath:downloadPath];
// This file has part of the download in it already
[request setTemporaryFileDownloadPath:@"/Users/ben/Desktop/my_work_in_progress.txt.download"];
[request setAllowResumeForFileDownloads:YES];
[request startSynchronous];
//The whole file should be here now.
NSString *theContent = [NSString stringWithContentsOfFile:downloadPath];
}
这只在下载数据到文件时有用,你必须设置allowResumeForFileDownloads为yes,为了:
任何你未来可能想恢复的下载(或者ASIHTTPRequest会在取消或释放时删除的临时下载)
任何你想恢复的下载
并且,你必须设置一个临时下载路径(setTemporaryFileDownloadPath),用不完整数据的路径,新数据将被追加到这个文件,当下载成功,这个文件会被移到downloadDestinationPath。
ASIHTTPRequest不会检查accept-range头(由于额外head请求的负担),因此仅在肯定服务器可以支持不完整下载时才使用此特征。
2五、
直接从磁盘流式请求body
自v0.96开始,ASIHTTPRequest可以使用磁盘文件做为请求body。这意味着将请求body保持在内存再也不必要,这样一来,大型的post/put操做的将极大的减小内存使用量。
你能够以几种方法来使用这一特征:
ASIFormDataRequests
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/ignore"];
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request setPostValue:@"foo" forKey:@"post_var"];
[request setFile:@"/Users/ben/Desktop/bigfile.txt" forKey:@"file"];
[request startSynchronous];
ASIFormDataRequests在你使用setFile:forKey:,自动使用这一特性。请求将建立临时文件,包含完整的请求body。文件 一次写入一些body的相关部分。请求被CFReadStreamCreateForStreamedHTTPRequest建立,使用此文件上的读取流 做为来源。
常规的ASIHTTPRequest
若是你知道你的请求将会很大,能够在请求上打开磁盘流(streaming from disk):
[request setShouldStreamPostDataFromDisk:YES];
在下面的例子中,咱们每次添加一个NSData对象。有两个方法作这个事 - 从内存添加数据(appendPostData:),或者使用appendPostDataFromFile从文件添加内容。
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/ignore"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setShouldStreamPostDataFromDisk:YES];
[request appendPostData:myBigNSData];
[request appendPostDataFromFile:@"/Users/ben/Desktop/bigfile.txt"];
[request startSynchronous];
在本例中,咱们想要直接put一个大文件。咱们本身设置setPostBodyFilePath,ASIHTTPRequest将使用这个文件做为post body。
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/ignore"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setRequestMethod:@"PUT"];
[request setPostBodyFilePath:@"/Users/ben/Desktop/another-big-one.txt"];
[request setShouldStreamPostDataFromDisk:YES];
[request startSynchronous];
很是重要:你不该该在上面任何方法的同一个请求中使用setPostBody - 他们是互斥的,setPostBody只能用于你本身构建请求body,并计划将请求body保留到内存的情型。
2六、
使用下载缓存
ASIDownloadCache 以及 ASICacheDelegate 的API在v1.8中已经改变,若是从v1.7升级的话,你须要更新你的代码。
特别是,缓存策略的可用选项是不一样的,而且你如今能够将多个缓存策略合并到单个请求中。
ASIHTTPRequest能够自动保存下载数据到一个缓存,以便之后使用。许多状况下这会颇有帮助:
你想要访问数据,在没有因特网链接不能从新下载时;
你想下载些东西,仅在你上次下载后它有了变化时;
你用的内容永不改变,因此你只想下载它一次;
在以前的ASIHTTPRequest版本中,处理以上状况意味着你本身手动保存这些数据。使用一个下载缓存能够在一些状况下减小你本身编写本地存储机制的需求。
ASIDownloadCache是一个简单的url缓存,能够被用于缓存get请求的响应。为了符合响应缓存的条件,请求必须成功(没有错误),服务器 必须返回一个200 ok的http响应码,或者从v1.8.1开始,支持301,302,303,307重定向的状态码。
开启响应缓存很简单:
[ASIHTTPRequest setDefaultCache:[ASIDownloadCache sharedCache]];
开启以后,全部的请求会自动使用缓存。若是你喜欢,你能够为独立的请求设置共享缓存:
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadCache:[ASIDownloadCache sharedCache]];
缓存不限于单个,你能够建立任意多个缓存。当你本身建立缓存时,必须设置缓存的存储路径 -这应该是一个可写的文件夹:
ASIDownloadCache *cache = [[[ASIDownloadCache alloc] init] autorelease];
[cache setStoragePath:@"/Users/ben/Documents/Cached-Downloads"];
// Don't forget - you are responsible for retaining your cache!
[self setMyCache:cache];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDownloadCache:[self myCache]];
2七、关于缓存策略
缓存策略是在信息存储于缓存中时你主要的控制方法,以及什么时候优先使用缓存的数据,而不是从新下载数据。
独立请求的缓存策略可使用它的cachePolicy属性。缓存策略使用位掩码(bitmask)定义,因此你能够组合多个选项来建立想要的策略:
// Always ask the server if there is new content available,
// If the request fails, use data from the cache even if it should have expired.
[request setCachePolicy:ASIAskServerIfModifiedCachePolicy|ASIFallbackToCacheIfLoadFailsCachePolicy];
你可使用下列选项来定义一个请求的缓存策略:
ASIUseDefaultCachePolicy
默认缓存策略,当你对请求应用此策略时,它会使用缓存的defaultCachePolicy,ASIDownloadCache的默认缓存策略是 ASIAskServerIfModifiedWhenStaleCachePolicy,你不该该将此策略和其余策略组合使用。
ASIDoNotReadFromCacheCachePolicy
请求不会从缓存读取数据
ASIDoNotWriteToCacheCachePolicy
请求不会保存到缓存
ASIAskServerIfModifiedWhenStaleCachePolicy
这是ASIDownloadCaches的默认缓存策略。使用了它,请求会首先查看缓存中是否有可用的缓存响应数据。若是没有,请求会照常进行。
若是有没有过时的缓存数据,请求会使用它而不去访问服务器。若是缓存数据过时了,请求将执行一个有条件的get去获取是否有可用的升级版本。若是服务器表 示缓存的数据就是最新的,那么缓存的数据将被使用,新的数据不会被下载。这时,缓存的过时时间(expiry date)将根据服务器新的过时时间而被更新。若是服务器提供了更新内容,则将被下载,新的数据和过时时间将被写入缓存。
ASIAskServerIfModifiedCachePolicy
这个策略和ASIAskServerIfModifiedWhenStaleCachePolicy相同,只是请求每次都会询问服务器是否有新的数据
ASIOnlyLoadIfNotCachedCachePolicy
只要存在缓存数据,老是会被使用,即便它已通过期。
ASIDontLoadCachePolicy
请求仅在响应已经被缓存时成功。若是请求没有任何响应被缓存,请求会终止,而且也不会为此请求设置错误。
ASIFallbackToCacheIfLoadFailsCachePolicy
若是请求失败,将会退回到缓存数据。若是失败后使用了缓存的数据,请求将会成功而不报错。你通常会将它和其余策略混合使用,由于此策略仅在发生问题时用于指定行为。
当你为缓存设置了defaultCachePolicy属性,全部的请求将会使用这个缓存策略,除非他们本身设置了自定义的策略。
2八、
关于存储策略
存储策略容许你定义特定响应的缓存将被保存多久,ASIHTTPRequest目前支持两种存储策略:
ASICacheForSessionDurationCacheStoragePolicy 是默认值。响应仅在会话期间被保存,并将在缓存首次使用后被删除,或者当调用[ASIHTTPRequest clearSession] 时被删除。
使用ASICachePermanentlyCacheStoragePolicy,缓存数据将被永久保存,要用这个存储策略,可将它设置到一个请求上:
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setCacheStoragePolicy:ASICachePermanentlyCacheStoragePolicy];
要手动清除缓存,调用clearCachedResponsesForStoragePolicy,传入你但愿清除的缓存数据的存储类型:
[[ASIDownloadCache sharedCache] clearCachedResponsesForStoragePolicy:ASICachePermanentlyCacheStoragePolicy];
2九、其余缓存特性
// 当你关掉shouldRespectCacheControlHeaders, 响应数据将被保存,即便服务器明确要求不要缓存他们
// (eg with a cache-control or pragma: no-cache header)
[[ASIDownloadCache sharedCache] setShouldRespectCacheControlHeaders:NO];
为请求设置secondsToCache,覆盖了由服务器设置的任何过时时间,一直保存响应数据直到secondsToCache秒到期。
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setSecondsToCache:60*60*24*30]; // Cache for 30 days
在请求运行后,didUseCachedResponse将在响应由缓存返回时,返回yes
[request didUseCachedResponse];
询问缓存请求数据的保存路径,这是使用下载缓存最高效的方式,由于数据没必要在请求完成后被拷贝到缓存
[request setDownloadDestinationPath:
[[ASIDownloadCache sharedCache] pathToStoreCachedResponseDataForRequest:request]];
写你本身的缓存
若是你已经有一个下载缓存,并想将它接入到ASIHTTPRequest,或者你想要写本身的缓存,可让你的缓存实现ASICacheDelegate协议。
30、节约带宽
从v1.0.7开始,ASIHTTPRequest可以限制全部请求使用的带宽,防止它超过一个用户定义的上限。这能够帮助收发大量数据的iphone应用经过app store的审核程序。
限流工做使用一个全局限制(以字节为单位),来限定每秒可以收发的数据总量。全部的请求共享这个限制。当他们收发数据时,ASIHTTPRequest追踪上一秒内有多少数据被收发。若是某个请求超过了限制,任何其余的执行单位也都必须等待本次测量时段结束。
在ios上,你可让ASIHTTPRequest自动打开限流,当你使用一个wwan(gprs/edge/3g)链接时,而当切换到wifi时,会自动关闭他。
当使用wwan激活时将限制带宽到为移动应用预约义的默认值,wifi请求不受影响,此方法仅限于ios
// Will limit bandwidth to the predefined default for mobile applications when WWAN is active.
// Wi-Fi requests are not affected
// This method is only available on iOS
[ASIHTTPRequest setShouldThrottleBandwidthForWWAN:YES];
当wwan激活后,限制带宽为用户定义的值,仅限ios
// Will throttle bandwidth based on a user-defined limit when when WWAN (not Wi-Fi) is active
// This method is only available on iOS
[ASIHTTPRequest throttleBandwidthForWWANUsingLimit:14800];
限制全部请求,无论是否是wifi,都会限制到预约义的值--当心使用
// Will prevent requests from using more than the predefined limit for mobile applications.
// Will limit ALL requests, regardless of whether Wi-Fi is in use or not - USE WITH CAUTION
[ASIHTTPRequest setMaxBandwidthPerSecond:ASIWWANBandwidthThrottleAmount];
记录每秒多少字节的数据被收发(从前5秒取平均值)
// Log how many bytes have been received or sent per second (average from the last 5 seconds)
NSLog(@"%qi",[ASIHTTPRequest averageBandwidthUsedPerSecond]);
很是重要:启用带宽限制以前先读读这个:
带宽限制应被视为一个实验性特征,使用时自行承担风险
不要将带宽限制过底,最好不要低于ASIWWANBandwidthThrottleAmount
你的应用实际使用的带宽将老是稍稍大于你设置的值,由于带宽测量不包括http头使用的带宽
ASIWWANBandwidthThrottleAmount不是官方的值,据我所知,官方没有发布带宽限制值
你不该该在你的应用并无大量数据传输时打开带宽限制,仅在有大量数据上传或下载的请求执行时启用它,其余时间请关闭。
3一、客户端证书支持
若是你的服务器须要使用客户端证书,v1.8之后能够经过请求来发送他们。
// Will send the certificate attached to the identity (identity is a SecIdentityRef)
[request setClientCertificateIdentity:identity];
// Add an additional certificate (where cert is a SecCertificateRef)
[request setClientCertificates:[NSArray arrayWithObject:(id)cert]];
在iphone/ipad app的ClientCertificateTests.m中有一个帮助函数,能够从pkcs12数据建立一个SecIdentityRef(此函数仅在ios中有用)。
3二、同代理一块儿工做
ASIHTTPRequest能够检测到系统代理而且自动将他们应用到请求。从v1.0.6开始,他也支持pac文件代理配置,以及验证代理。
默认的,ASIHTTPRequest将尝试自动检测代理设置,可是,你可能但愿可以手动设置代理:
// Configure a proxy server manually
NSURL *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"]];
验证代理
在mac os上,ASIHTTPRequest能够自动检测用于验证代理的证书,若是他们在系统参数中指定了的话。在ios上,则不能自动检测,因此你要么手动设 置他们,使用委托来询问控制器/相应证书的用户,要么让ASIAuthenticationDialog询问用户。一旦有效的代理证书被接受,他们将被保 存到键链中(当useKeychainPersistence被打开)并自动被重用。
手动指定代理的证书
NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/ignore"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setProxyHost:@"192.168.0.1"];
[request setProxyPort:3128];
// Set a username and password for authenticating proxies
[request setProxyUsername:@"bencopsey"];
[request setProxyPassword:@"password"];
// For NTLM proxies, you can also set the domain (NTLM proxies are untested!)
[request setProxyDomain:@"la.la.land"];
使用委托来询问代理证书
这和使用委托提供常规验证证书的方式同样,除了委托必须响应proxyAuthenticationNeededForRequest(之前的名字是proxyAuthorizationNeededForRequest)。
使用内置验证对话框(目前仅ios)
v1.0.8以后新增了ASIAuthenticationDialog类。这个类可被用于询问用户web服务器或代理的验证证书。
若是你的委托不能响应proxyAuthenticationNeededForRequest,默认的,ASIHTTPRequest将显示一个提示用 户提供证书的对话框。它默认为代理服务器显示,这样全部使用ASIHTTPRequest的应用能够同验证代理工做,而不须要任何开发者端额外的努力。
同步请求时,代理验证对话框不会显示。
若是你不喜欢用代理验证对话框,要么你在你的代理中实现proxyAuthenticationNeededForRequest,或者将 shouldPresentProxyAuthenticationDialog设置为false(那样你的应用将不能链接到验证代理)。若是你想改变它 的外观,子类化ASIHTTPRequest并覆盖showProxyAuthenticationDialog来显示你的自定义对话框,或者子类化 ASIAuthenticationDialog。
3三、其余特性
自定义用户代理
设置你的应用将使用的用户代理:
[ASIHTTPRequest setDefaultUserAgentString:@"MyApp 1.0"]
若是你不设置用户代理,ASIHTTPRequest会为你建立一个,例如(对于mac os 程序):
My Application 1.0 (Macintosh; Mac OS X 10.5.7; en_GB)
你也能够为每一个请求设置用户代理:
[request setUserAgent:@"MyApp 1.0"]
在ios中程序进入后台时继续请求
// iOS 4+ only
[request setShouldContinueWhenAppEntersBackground:YES];
监视网络活动
// Log the average bandwidth used (in bytes) per second over the last 5 seconds
NSLog(@"%llu",[ASIHTTPRequest averageBandwidthUsedPerSecond]);
if ([ASIHTTPRequest isNetworkInUse]) {
// ASIHTTPRequest has requests in progress that are using the network
}
禁用自动更新网络活动指示器(仅ios)
默认的,ASIHTTPRequest会显示网络活动指示器(在状态条上),当你的请求使用网络时。若是你想要本身管理这个,你能够禁用这些更新:
[ASIHTTPRequest setShouldUpdateNetworkActivityIndicator:NO];
当请求超时自动重试
请求超时,最多重试2次:
[request setNumberOfTimesToRetryOnTimeout:2];
配置持续链接(persistent connection)
默认的,ASIHTTPRequest将尝试保持到服务器的链接,这样他们能够被连到相同服务器的请求重用(这通常致使速度显著提高,特别是你有许多小的请求时)。
当链接到http1.1服务器时,持续链接将自动启用,或者当服务器发回一个keep-alive头时。当服务器明确的发回一个Connection: close头时,持续链接将被关闭。另外,ASIHTTPRequest对于包含body的请求(如post/put),将不会使用持续链接。你能够强制 这些请求使用持续链接,手动设置请求方法,而后将持续链接从新打开:
[request setRequestMethod:@"PUT"];
[request setShouldAttemptPersistentConnection:YES];
许多服务器不在响应头中提供链接保持多久的信息,因此可能在请求完成后的任什么时候间关闭链接。若是服务器不发送任何此类信息,ASIHTTPRequest将在请求完成后60秒内保持链接。有赖于你的服务器配置,这个时间可能过长或太短。
若是这个超时过长,服务器将在下一个请求有机会用它前踢掉你,若是ASIHTTPRequest碰到关闭链接的错误,它将在一个新链接上重试这个请求。
若是这个超时太短,服务器可能很乐意保持这个链接更久,可是ASIHTTPRequest将没必要要的重开一个新链接,这会招致效率上的惩罚。
// 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];
强制使用http 1.0
[request setUseHTTPVersionOne:YES];
禁用安全证书验证
你可能但愿使用这个测试你有一个自签名的安全证书。我推荐从一个可信的证书机构购买证书,而且只为产品程序打开证书验证。
[request setValidatesSecureCertificate:NO];
3四、调试选项 ASIHTTPRequest提供了一些有助于调试请求行为的标志。这些标志能够在ASITHHPRequestConfig.h中找到。 当你打开这些标志后,请求会把他们干的事打印到控制台。 DEBUG_REQUEST_STATUS 打印整体请求的生命周期信息 -- 开始,结束上传,结束下载 等等。 DEBUG_THROTTLING 打印(粗略的)有多少带宽被使用的信息,若是请求被限流,还包括这如何发生的信息。同DEBUG_REQUEST_STATUS联合使用,可能对调试超时有帮助,由于你能够看到在哪一点请求中止了收发数据。 DEBUG_PERSISTENT_CONNECTIONS 打印请求如何重用持续链接的信息,若是你看到输出下面的信息: Request attempted to use connection #1, but it has been closed - will retry with a new connection …这表示你设置到persistentConnectionTimeoutSeconds的值可能太高,参看“配置持续链接”小节得到更多信息。 DEBUG_HTTP_AUTHENTICATION 从v1.8.1后添加,这会打印出关于请求如何处理http验证(基本/摘要/ntml)的信息。 DEBUG_FORM_DATA_REQUEST 打印ASIFormDataRequest将发送的请求body的概要。仅在使用ASIFormDataRequest有用。