原理:定义接口通过传入网络地址url和地址参数parameters来进行网络请求的调用,同时将请求的结果以代理的方式来进行回调。
首先,创建一个继承于NSObject的类,在.h文件中设置代理协议及方法,并声明代理和接口方法。代码如下:
#import <Foundation/Foundation.h>
@protocol RHURLRequestDelegate;
@interface RHURLRequest : NSObject
//代理属性
@property (nonatomic, weak)id<RHURLRequestDelegate> delegate;
//POST请求接口方法
- (void)startPOSTRequestWithUrl:(NSString *)url parameters:(NSDictionary *)parameters;
//GET请求接口方法
- (void)startGETRequestWithUrl:(NSString *)url parameters:(NSDictionary *)parameters;
@end
/代理协议及方法
@protocol RHURLRequestDelegate <NSObject>
//请求成功回调的方法,参数为请求得到的解析之后的数据
- (void)requestDidSuccessData:(id)data;
//请求失败回调的方法,参数为请求失败的错误信息
- (void)requestDidFailedError:(NSError *)error;
@end
接着就是在.m文件中实现声明的接口方法,具体代码及注释如下:
#import "RHURLRequest.h"
@implementation RHURLRequest
//POST请求 url为传入的网址, parameters为请求的参数以字典形式传入
- (void)startPOSTRequestWithUrl:(NSString *)url parameters:(NSDictionary *)parameters {
// 将参数添加在请求体中
NSMutableString * str = [NSMutableString string];
//参数处理
for (NSString * key in parameters) {
[str appendFormat:@"%@=%@&", key, parameters[key]];
}
// 创建请求体
NSData * body = [str dataUsingEncoding:NSUTF8StringEncoding];
// 创建URL
NSURL * URL = [NSURL URLWithString:url];
// 创建可变请求对象
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
// 设置请求方法
[request setHTTPMethod:@"POST"];
// 设置请求体
[request setHTTPBody:body];
// 实例化网络会话.
NSURLSession *session = [NSURLSession sharedSession];
// 根据请求对象创建请求任务
NSURLSessionDataTask * task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (!error) {
//请求成功 对请求的数据做初步的json解析
id object = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
//回调代理方法,并传入请求结果
if ([self.delegate respondsToSelector:@selector(requestDidSuccessData:)]) {
[self.delegate requestDidSuccessData:object];
}
}else {
//请求失败 回调代理方法,并传入错误信息
if ([self.delegate respondsToSelector:@selector(requestDidFailedError:)]) {
[self.delegate requestDidFailedError:error];
}
}
}];
// 开启任务. //这一步很关键,如果没有这一步,请求任务不会执行
[task resume];
}
//GET请求 url为传入的网址, parameters为请求的参数以字典形式传入
- (void)startGETRequestWithUrl:(NSString *)url parameters:(NSDictionary *)parameters {
//GET请求需要将参数拼接在url后面
//网络接口和参数 以“?”分隔. 参数和参数之间以“&”符号分隔。
// 拼接url及参数
NSMutableString * str = [NSMutableString string];
[str appendString:url];
//当有参数时将参数拼接上去(小编在此做的是url没有拼接参数情况下,如果url已经拼接了参数,这里还传入了一些参数,那么此处的判断需要更改,具体的大家可以来实现)
if (parameters.count > 0) {
//小编在此对url时候以"?"结尾做了判断,有的话就不需要再拼接"?"
if (![str hasSuffix:@"?"]) {
[str appendString:@"?"];
}
//拼接参数
for (NSString * key in parameters) {
[str appendFormat:@"%@=%@&", key, parameters[key]];
}
//注意最后一个"&"符号需要去掉
[str deleteCharactersInRange:NSMakeRange(str.length - 1, 1)];
}
// 设置URL
NSURL * URL = [NSURL URLWithString:str];
// 实例化网络会话.
NSURLSession * session = [NSURLSession sharedSession];
//根据URL创建请求任务
NSURLSessionDataTask * task = [session dataTaskWithURL:URL completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (!error) {
//请求成功 对请求的数据做初步的json解析
id object = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
//回调代理方法,并传入请求结果
if ([self.delegate respondsToSelector:@selector(requestDidSuccessData:)]) {
[self.delegate requestDidSuccessData:object];
}
}else {
//请求失败 回调代理方法,并传入错误信息
if ([self.delegate respondsToSelector:@selector(requestDidFailedError:)]) {
[self.delegate requestDidFailedError:error];
}
}
}];
// 开启任务. //这一步很关键,如果没有这一步,请求任务不会执行
[task resume];
}
@end
OK!到此我们就封装好了一个简单的网络请求的类,能够实现POST和GET请求,请求速度还是很快的。如果平时工作中遇到了AFNetworking请求总是出错的问题的时候,不妨尝试一个该类,说不定会有给我们惊喜的哦!
#import "ViewController.h"
#import "RHURLRequest.h"
@interface ViewController () <RHURLRequestDelegate>
@property (nonatomic, strong) RHURLRequest * request;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//由于没有现成可公开的接口来测试,所以这里就留给大家来填写测试了
//传入相应的参数开始POST请求
[self.request startPOSTRequestWithUrl:@"" parameters:@{}];
//传入相应的参数开始GET请求
[self.request startGETRequestWithUrl:@"" parameters:@{}];
}
#pragma mark - request delegate
//请求成功回调的代理方法,data为请求的json解析之后的结果
- (void)requestDidSuccessData:(id)data {
NSLog(@"%@", data);
}
//请求失败回调的代理方法,error为错误信息
- (void)requestDidFailedError:(NSError *)error {
NSLog(@"%@", error.localizedDescription);
}
#pragma mark - 懒加载
- (RHURLRequest *)request {
if (!_request) {
_request = [[RHURLRequest alloc] init];
_request.delegate = self;
}
return _request;
}
@end