ASIHttpRequest使用详解(2)

创建和执行Request

一、创建一个同步请求

  1. 这是ASIHttpRequest最简单的使用方式。
  2. 通过发送startSynchronous消息在同一线程中执行请求,当请求完成时(不管请求成功还是失败)返回控制。
  3. 通过检查error属性来检测错误
  4. 同步请求会阻塞主线程的执行,这导致用户界面不响应用户操作,任何动画都会停止渲染。
  5. 如果请求string数据,则使用responseString方法;如果请求二进制数据(图片,音乐,视频等),则使用responseData方法;如果下载文件,则使用downloadDestinationPath属性来指定路径
示例代码
- (IBAction)grabURL:(id)sender //一般执行请求时都是点击了某个Button(最为常见),所以此处使用IBAction
{
  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]; //同步请求中,将startSynchronous和error写在了一个方法里面
  }
}

二、创建一个异步请求

跟上面的基本原理是相同的,只是请求在后台执行,不会阻塞主进程的执行

示例代码
- (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
{
   NSString *responseString = [request responseString]; //获取string数据(如用户名和密码)
    
   NSData *responseData = [request responseData]; //获取二进制数据(图片、视频、音乐)
}
 
- (void)requestFailed:(ASIHTTPRequest *)request
{
   NSError *error = [request error]; //返回错误信息
}

三、使用blocks

  1. 在平台支持情况下,ASIHTTPRequest1.8以上支持block。
  2. 声明request时要使用__block修饰符,这是为了告诉block不要retain request,以免出现retain循环,因为request是会retain block的。
示例代码
- (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];
}

四、使用队列

  1. 通过使用NSOperationQueue或者 ASINetworkQueue,我们可以在异步请求中创建更多的控制进程。
  2. 当使用队列时,在同一时间只能运行确定数目的请求。
  3. 他定义了maxConcurrentOperationCount属性,表示同一时间的最大并发连接数,如果超过了这个数值,请求必须等待其他请求完成后才会开始执行
  4. 如果需要对队列里面的每个request进行区分,那么可以设定request的userInfo属性,它是个NSDictionary,或者更简单的方法是设定每个request的tag属性,这两个属性都不会被发送到服务器。
  5. 不要使用request的URL来区分每个request,因为URL可能会改变(例如重定向),如果需要使用request的URL,使用[request originalURL],这个将永远返回第一个url。
示例代码
- (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:)]; //注意此处使用了@selector,下面有详解
   [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];
}

注意:此代码中使用了@selector,这是因为此代码重新定义了请求成功和失败的方法;如果不设定selector,那么系统会使用默认的requestFinished: 和 requestFailed:方法

五、关于ASINetworkQueue

ASINetworkQueue是NSOperationQueue的子类,提供更高级的特性(ASINetworkQueue的代理函数):
requestDidStartSelector
//当一个request开始执行时,这个代理函数会被调用。
requestDidReceiveResponseHeadersSelector
//当队列中的request收到服务器返回的头信息时,这个代理函数会被调用。对于下载很大的文件,这个通常比整个request的完成要早。
requestDidFinishSelector
//当每个request完成时,这个代理函数会被调用。
requestDidFailSelector
//当每个request失败时,这个代理函数会被调用。
queueDidFinishSelector
//当队列完成(无论request失败还是成功)时,这个代理函数会被调用。
注意:
  1. ASINetworkQueues与NSOperationQueues稍有不同,加入队列的request不会立即开始执行。如果队列打开了进度开关,那么队列开始时,会先对所有GET型request进行一次HEAD请求,获得总下载大小,然后真正的request才被执行。
  2. 当ASINetworkQueue中的一个request失败时,默认情况下,ASINetworkQueue会取消所有其他的request。要禁用这个特性,设置 [queue setShouldCancelAllRequestsOnFailure:NO]
  3. ASINetworkQueues只可以执行ASIHTTPRequest操作,而不可以用于通用操作。试图加入一个不是ASIHTTPRequest的NSOperation将会导致发生错误。
       向一个已经开始进行的ASINetworkQueue 加入request会怎样?
如果你使用ASINetworkQueue来跟踪若干request的进度,只有当新的request开始执行时,总进度才会进行自适应调整(向后移动)。ASINetworkQueue不会为队列开始后才加入的request进行HEAD请求,所以如果你一次向一个正在执行的队列加入很多request,那么总进度不会立即被更新。
如果队列已经开始了,不需要再次调用[queue go]。

六、取消异步请求

  1. 取消一个异步请求(无论request是由[request startAsynchronous]开始的还是从你创建的队列中开始的),使用[request cancel]即可。注意同步请求不可以被取消
  2. 如果你取消了一个request,那么这个request将会被视为请求失败,并且request的代理或者队列的代理的失败代理函数将被调用。
  3. 如果你不想让代理函数被调用,那么将delegate设置为nil,或者使用clearDelegatesAndCancel方法来取消request。clearDelegatesAndCancel 将会首先清除所有的代理和block。
  4. 当使用ASINetworkQueue时,如果取消了队列中的一个request,那么队列中其他所有request都会被取消,可以设置shouldCancelAllRequestsOnFailure的值为NO来避免这个现象。
示例代码
[request cancel] // 取消一个异步请求
 
[request clearDelegatesAndCancel]; //取消一个异步请求,首先要清除所有的delegates和blocks

[queue setShouldCancelAllRequestsOnFailure:NO]; //当队列中的一个请求失败或者取消,其他的请求可以继续运行 

[queue cancelAllOperations]; // 取消队列中所有的请求

七、发送数据

1.设定request头

ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request addRequestHeader:@"Referer" value:@"http://allseeing-i.com/"]; //添加请求头

2.使用ASIFormDataRequest POST表单

  1. 要想使用兼容的方式POST一个表单,必须使用ASIFormDataRequest这个类
  2. 通常数据是以’application/x-www-form-urlencoded’格式发送的,如果上传了二进制数据或者文件,那么格式将自动变为‘multipart/form-data’ 
  3. 文件中的数据是需要时才从磁盘加载,所以只要web server能处理,那么上传大文件是没有问题的
示例代码
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:方法POST的文件mime头,如果你想自定义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"];
 

3.你可以通过使用add这个非正式的API来为同一个参数发送多个值

ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:url];
[request addPostValue:@"Ben" forKey:@"names"]; //以前使用的是setPostValue,此处使用的是addPostValue,这个要注意
[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中所有的发送数据的方法

// Add a POST variable to the request
- (void)addPostValue:(id <NSObject>)value forKey:(NSString *)key;

// Set a POST variable for this request, clearing any others with the same key
- (void)setPostValue:(id <NSObject>)value forKey:(NSString *)key;

// Add the contents of a local file to the request
- (void)addFile:(NSString *)filePath forKey:(NSString *)key;

// Same as above, but you can specify the content-type and file name
- (void)addFile:(NSString *)filePath withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key;

// Add the contents of a local file to the request, clearing any others with the same key
- (void)setFile:(NSString *)filePath forKey:(NSString *)key;

// Same as above, but you can specify the content-type and file name
- (void)setFile:(NSString *)filePath withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key;

// Add the contents of an NSData object to the request
- (void)addData:(NSData *)data forKey:(NSString *)key;

// Same as above, but you can specify the content-type and file name
- (void)addData:(id)data withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key;

// Add the contents of an NSData object to the request, clearing any others with the same key
- (void)setData:(NSData *)data forKey:(NSString *)key;

// Same as above, but you can specify the content-type and file name
- (void)setData:(id)data withFileName:(NSString *)fileName andContentType:(NSString *)contentType forKey:(NSString *)key;

注意:
set方法会清除同一个key的其他值,add方法只是在原来不变的情况下,给key增加更多的值

4.PUT请求、自定义POST请求

如果你想发送PUT请求,或者你想自定义POST请求,使用 appendPostData: 或者 appendPostDataFromFile:这两个方法
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request appendPostData:[@"This is my data" dataUsingEncoding:NSUTF8StringEncoding]];
//当你使用appendPostData: / appendPostDataFromFile: / setPostBody:等方法时,默认的是POST请求方式
[request setRequestMethod:@"PUT"]; //改变请求方式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值