ASIHTTPRequest框架是优秀的第三方Objective-C的HTTP框架,支持Mac OS X和iOS下的HTTP开发。
https://allseeing-i.com/ASIHTTPRequest
https://github.com/pokeb/asi-http-request
ASIHTTPRequest具有如下优点:
1、支持下载数据入在内存或本地文件;
2、容易访问请求和应答HTTP或本地文件;
3、支持Cookie;
4、支持GZIP请求或应答;
5、支持缓存;
6、支持同步或异步请求;
7、支持HTTPS。
安装、配置ASIHTTPRequest框架
1、下载ASIHTTPRequest框架
下载地址:https://github.com/pokeb/asi-http-request/tree
2、添加ASIHTTPRequest文件
文件分别是:
ASIAuthenticationDialog.h
ASIAuthenticationDialog.m
ASICacheDelegate.h
ASIDataCompressor.h
ASIDataCompressor.m
ASIDataDecompressor.h
ASIDataDecompressor.m
ASIDownloadCache.h
ASIDownloadCache.m
ASIFormDataRequest.h
ASIFormDataRequest.m
ASIHTTPRequest.h
ASIHTTPRequest.m
ASIHTTPRequestConfig.h
ASIHTTPRequestDelegate.h
ASIInputStream.h
ASIInputStream.m
ASINetworkQueue.h
ASINetworkQueue.m
ASIProgressDelegate.h
Reachability.h
Reachability.m
3、添加相关类库或框架
CFNetwork.framework
SystemConfiguration.framework
MobileCoreServices.framework
CoreGraphics.framework
libz.dylib
添加方法:点击左侧栏项目名称——再点击右侧出现的TARGET下的项目名称——选择Build Phases——选择Link Binary With Libraryes——点击“+”——在弹出框中选择所需框架——点击“Add”完成添加。
4、但ASIHTTPRequest框架不支持ARC,如果在ARC下开发必须进行相关的设置,即将ASIHTTPRequest框架的相关文件设置为“-fno-objc-arc”,以便支持ARC模式。
具体设置方法是:点击左侧栏项目名称——再点击右侧出现的TARGET下的项目名称——选择Build Phases——选择Compile Sources——选择ASIHTTPRequest相关文件,同时将“Compiler Flags”属性设置为“-fno-objc-arc”。
使用
在ASIHTTPRequest框架中与HTTP请求相关的类有ASIHTTPRequest和ASIFormDataRequest,其中最常用的是ASIHTTPRequest,而ASIFormDataRequest是ASIHTTPRequest的子类,ASIFormDataRequest可以发送类似于HTML中的表单数据,也可以上传数据,默认采用的是POST请求方法。也可以用其他的HTTP请求方法。
它们都可以进行同步或异步的请求。
1、实现GET同步请求
注意:使用ASIHTTPRequest类时,需引入头文件ASIHTTPRequest.h
#import "ASIHTTPRequest.h"
- (void)startRequest
{
NSString *strURL= [[NSString alloc] initWithFormat:@"http://iosbook3.com/service/mynotes/webservice.php?email=%@&type=%@&action=%@", @"<你的邮箱iosbook3.com用户邮箱>", @"JSON", @"query"];
NSURL *url = [NSURL URLWithString:[strURL URLEncodedString]];
// 创建ASIHTTPRequest请求对象
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
// 同步请求
[request startSynchronous];
// 调用请求对象的error方法
NSError *error = [request error];
if (!error)
{
// 调用请求对象的responseData方法,获得从服务器应答回来的结果(如果返回是字符串,则使用responseString)
NSData *date = [request responseData];
NSDictionary *resDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
NSLog(@"result %@", resDict);
}
}
2、实现POST同步请求
注意:发送POST方法的请求时,不使用是同步还是异步都是使用ASIFormDataRequest类,需引入ASIFormDataRequest.h头文件。
#import "ASIFormDataRequest.h"
- (void)startRequest
{
NSString *strURL = @"http://iosbook3.com/service/mynotes/webservice.php";
NSURL *url = [NSURL URLWithString:[strURL URLEnodedString]];
// 创建请求对象
ASIFormDataRequest *request = [ ASIFormDataRequest requestWithURL:url];
// 设置POST参数
[request setPostValue:@"<你的iosbook3.com用户邮箱>" forKey:@"email"];
[request setPostValue:@"JSON" forKey:@"type"];
[request setPostValue:@"query" forKey:@"action"];
// 发送同步请求
[request startSynchronous];
NSError *error = [request error];
if (!error)
{
NSData *data = [request responseData];
NSDictionary *resDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
NSLog(@"result %@", resDict);
}
}
特别说明:通过设置requestMehtod属性可以设置请求的方法,如GET,POST,PUT等,设置方法为:
[request setRequestMethod:@"PUT"];
3、异步请求
异步请求在用户体验方面要比同步请求好。因为同步请求过程中,只有同步请求完成后才能进行下一步的操作。而异步请求,则是在请求过程中还可能进行其他的操作,在异步请求完成或失败后,通过调用其代码委托方法实现需要的功能。
注意:使用时,除了引入ASIHTTPRequest.h头文件后,还需要设置协议ASIHTTPRequestDelegate。在使用过程中,可以使用框架自带的回调方法,也可使用自定义的回调方法,还可以使用代码块。
// 方法1 使用系统自带回调方法
- (void)startRequest
{
NSString *strURL= [[NSString alloc] initWithFormat:@"http://iosbook3.com/service/mynotes/webservice.php?email=%@&type=%@&action=%@", @"<你的邮箱iosbook3.com用户邮箱>", @"JSON", @"query"];
NSURL *url = [NSURL URLWithString:[strURL URLEncodedString]];
// 创建ASIHTTPRequest请求对象
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
// 设置代理
[request setDelegate:self];
// 异步请求
[request startAsynchronous];
}
// 回调方法(使用ASIHTTPRequest框架回调方法)
- (void)requestFinished:(ASIHTTPRequest *)request
{
NSData *data = [request responseData];
NSDictionary *resDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
NSLog(@"result %@", resDict);
}
- (void)requestFailed:(ASIHTTPRequest *)request
{
NSError *error = [request error];
NSLog:(@"%@", [error localizedDescription];
}
// 方法2 使用自定义回调方法
- (void)startRequest
{
NSString *strURL= [[NSString alloc] initWithFormat:@"http://iosbook3.com/service/mynotes/webservice.php?email=%@&type=%@&action=%@", @"<你的邮箱iosbook3.com用户邮箱>", @"JSON", @"query"];
NSURL *url = [NSURL URLWithString:[strURL URLEncodedString]];
// 创建ASIHTTPRequest请求对象
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
// 设置代理
[request setDelegate:self];
// 不使用框架自带的回调方法时,可以自定义回调方法
[request setDidFinishSelector:@selector(requestSuccess:)]; // 成功时
[request setDidFailSelector:@selector(requestError:)]; // 失败时
// 异步请求
[request startAsynchronous];
}
// 回调方法(使用自定义回调方法)
- (void)requestSuccess:(ASIHTTPRequest *)request
{
NSData *data = [request responseData];
NSDictionary *resDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
NSLog(@"result %@", resDict);
}
- (void)requestError:(ASIHTTPRequest *)request
{
NSError *error = [request error];
NSLog:(@"%@", [error localizedDescription];
}
// 方法3 使用代码块方法
// 注意:使用代码块的时候,要特别注意Retain Cycle,即死循环,所以要将对象设置标识符“__weak”(表示弱引用,针对ARC模式),或者是“__block”(针对MRC模式)
- (void)startRequest
{
NSString *strURL= [[NSString alloc] initWithFormat:@"http://iosbook3.com/service/mynotes/webservice.php?email=%@&type=%@&action=%@", @"<你的邮箱iosbook3.com用户邮箱>", @"JSON", @"query"];
NSURL *url = [NSURL URLWithString:[strURL URLEncodedString]];
// 创建ASIHTTPRequest请求对象
__weak ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
// 成功时的代码块
[request setCompletionBlock:^{
NSData *data = [request responseData];
NSDictionary *resDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
NSLog(@"result %@", restrict);
}];
// 失败时的代码块
[request setFailedBlock:^{
NSError *error = [request error];
NSLog:(@"%@", [error localizedDescription];
}];
// 异步请求
[request startAsynchronous];
}
// 注意:在使用过程中,注意网络请求的处理
[request clearDelegatesAndCancel];
request.delegate = nil;
4、请求队列的应用
ASIHTTPRequest.h
ASINetworkQueue.h
NSNumber+Message.h
NSString+URLEncoding.h
@property (weak, nonatomic) UIImageView *imageView1;
@property (weak, nonatomic) UIImageView *imageView2;
@property (strong, nonatomic) ASINetworkQueue *networkQueue;
- (void)setASINetworkQueue
{
// 创建队列对象
if (!self.networkQueue)
{
self.networkQueue = [[ASINetworkQueue alloc] init];
}
// 停止以前的队列
[self.networkQueue cancelAllOperations];
// 创建ASI队列
// 设置对列代理
[self.networkQueue setDelegate:self];
// 设置请求成功回调方法
[self.networkQueue setRequestDidFinishSelector:@selector(requestFinished:)];
// 设置请求失败回调方法
[self.networkQueue setRequestDidFailSelector:@selector(requestFailed:)];
// 设置队列完成回调方法
[self.networkQueue setQueueDidFinishSelector:@selector(queueFinished:)];
for (int i = 0; i < 3; i++)
{
NSString *strURL = [NSString alloc] initWithFormat:@"http://iosbook3.com/service/download.php?email=%@&FileName=test%i.jpg", @"<你的iosbook3.com用户邮箱>", i];
NSURL *url = [NSURL URLWithString:[strURL URLEncodedString]];
// 创建请求对象
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
// 设置请求对象tag值,对便于区分请求对象(还可以通过设置userInfo属性进行区分,即request.userInfo =[NSDictionary dictionaryWithObjectsAndKeys:@"番薯大佬", @"name", nil])
request.tag = i;
// 将请求对象加入到队列中
self.networkQueue addOperation:request];
}
// 执行队列
[self.networkQueue go];
}
// 回调方法
- (void)requestFinished:(ASIHTTPRequest *)request
{
NSData *data = [request responseData];
NSError *error;
NSDictionary *resDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSOReadingAllowFragments error:&error];
if (!resDict)
{
UIImage *image = [UIImage imageWithData:data];
if (1 == request.tag)
{
self.imageView1.image = image;
}
else
{
self.imageView2.image = image;
}
}
else
{
NSNumber *resultCodeObj = [resdict objectForKey:@"ResultCode"];
NSString *errorStr = [resultCodeObj errorMessage];
UIAlertView *alertView = [UIAlertView alloc] initWithTitle:@"错误信息” message:errorStr delegate:nil cancelButotnTitle:@"OK"otherButtonTitles:nil];
[alertView show];
}
if (0 == [self.networkQueue requestsCount])
{
[self setNetworkQueue:nil];
}
}
- (void)requestFailed:(ASIHTTPRequest *)request
{
NSError *error = [request error];
NSLog(@"%@", [error localizedDescription];
if (0 == [self.networkQueue requestsCount])
{
[self setNetworkQueue:nil];
}
}
- (void)queueFinished:(ASIHTTPRequest *)request
{
if (0 == [self.networkQueue requestsCount])
{
[self setNetworkQueue:nil];
}
}
#import "ASIFormDataRequest.h"
步骤2 设置协议
ASIHTTPRequestDelegate
步骤3 设置相关方法
- (void)setUpoad
{
NSString *strURL = @"http://iosbook3.com/service/upload.php";
NSURL *url1 = [NSURL URLWithString:[strURL URLEncodedString]];
// 创建请求对象
ASIFormDataRequest *request = [ASIFormDatRequest requestWithUrl:url1];
// 提交数据使用setPostValue等方法
[request setPostValue:@"<你的iosbook3.com用户邮箱>" forKey:@"email"];
// 获取要上传的文件
NSString *path = [[NSBundle mainBundle] pathForResource:@"test1" ofType:@"jpg"];
// 上传文件,相当于HTML表单中的上传控件
[request setFile:path forKey:@"file"];
// 设置代理
[request setDelegate:self];
// 重写协议方法
[request setDidFinishSelector:@selector(requestSuccess:)];
[request setDidFailSelector:@selector(requestError:)];
// 请求开始
[request startAsynchronous];
}
// 回调方法
- (void)requestSuccess:(ASIHTTPRequest *)request
{
NSData *data = [request responseData];
NSError *error;
NSDictionary *resDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
if (!resDict)
{
// do something
}
else
{
NSNumber *resultCodeObj = [resDict objectForKey:@"ResultCode"];
NSString *errorStr = [resultCodeObj errorMessage];
UIAlertVIEW *alertView = [[UIAlertView alloc] intiWithTitle:@"错误信息" message:errorStr delegate:nilcancelButtonTtile:@"OK" otherButtonTitles:nil];
[alertView show];
}
}
- (void)requestError:(ASIHTTPRequest *)request
{
NSError *error = [request error];
NSLog(@"%@", [error localizedDescription]);
}