@chenbinghua
2017-01-18T04:01:25.000000Z
字数 3635
阅读 1846
博客文章
前言:网上有很多通过直接查看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"// 请求成功的blocktypedef void (^MyHTTPSessionSuccessBlock)(NSURLSessionDataTask *task, id responseObject);// 请求失败的blocktypedef 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 *)methodURLString:(NSString *)URLStringparameters:(NSDictionary *)parameterssuccess:(void (^)(NSURLSessionDataTask *task, id responseObject))successfailure:(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