@chenbinghua
2017-01-18T12:01:25.000000Z
字数 3635
阅读 1631
博客文章
前言:网上有很多通过直接查看AFNwetworking(以下省称AFN)源代码来阐述其实现原理的文章,但是本系列文章希望从另外一个角度来解读AFN, 即通过一步一步动手实现自己的AFN,从最简单的基本功能到最后的完善。
假设我们iOS圈没有AFNwetworking、ASIHTTPRequest等网络请求库,你会动手从零开始写出一个自己的网络请求库吗?
参考AFNwetworking3.x为例,此库实现主要功能有:
万丈高楼从低起,我们从封装发送普通Http请求
这个最简单的功能开始。
其中我们最常用的功能是发送普通Http请求,我们首先看看AFN发送get、post的基本使用:
// 发送get请求
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
[manager GET:@"http://localhost" parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {
// 处理网络的进度
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
// 请求成功的回调 responseObject默认是json数据
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
// 请求失败的回调
}];
// 发送post请求
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
// 设置请求参数
NSMutableDictionary *param = [NSMutableDictionary dictionary];
param[@"name"] = @"chenbinghua";
[manager GET:@"http://localhost" parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {
// 处理网络的进度
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
// 请求成功的回调 responseObject默认是json数据
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
// 请求失败的回调
}];
在AFNAFNwetworking2.x的时候,发送请求是用NSURLConnection。到了后来,用了功能更为牛逼的NSURLSession。
以下是NSURLSession发送get、post请求的方法:
#import "MyHTTPSessionManager.h"
// 请求成功的block
typedef void (^MyHTTPSessionSuccessBlock)(NSURLSessionDataTask *task, id responseObject);
// 请求失败的block
typedef void (^MyHTTPSessionFailureBlock)(NSURLSessionDataTask *task, NSError *error);
#pragma mark -
@interface MyHTTPSessionManager()<NSURLSessionDataDelegate>
@property (nonatomic, copy) MyHTTPSessionSuccessBlock success;
@property (nonatomic, copy) MyHTTPSessionFailureBlock failure;
@property (nonatomic,strong) id responseObject;
@end
@implementation MyHTTPSessionManager
- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
URLString:(NSString *)URLString
parameters:(NSDictionary *)parameters
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
{
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
self.success = success;
self.failure = failure;
// 2.创建请求
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:URLString]];
request.HTTPMethod = method; // 请求方法
request.HTTPBody = [[self httpBodyWithDictionary:parameters] dataUsingEncoding:NSUTF8StringEncoding]; // 请求体
// 创建任务
NSURLSessionDataTask *task = [session dataTaskWithRequest:request];
// 启动任务
[task resume];
return task;
}
- (NSString *)httpBodyWithDictionary:(NSDictionary *)dic{
NSMutableString *bodyString = [NSMutableString string];
for (NSString *key in dic) {
[bodyString appendFormat:@"%@=%@&",key,dic[key]];
}
return bodyString;
}
#pragma mark - <NSURLSessionDataDelegate>
/**
* 1.接收到服务器的响应
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
// 允许处理服务器的响应,才会继续接收服务器返回的数据,只能放在最后
completionHandler(NSURLSessionResponseAllow);
}
/**
* 2.接收到服务器的数据(可能会被调用多次)
*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
self.responseObject = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
}
/**
* 3.请求成功或者失败(如果失败,error有值)
*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionDataTask *)task didCompleteWithError:(NSError *)error
{
if (error) {
if (self.failure) {
self.failure(task,error);
}
}else{
if (self.success) {
self.success(task,self.responseObject);
}
}
}
@end