[关闭]
@chenbinghua 2017-01-18T12:01:25.000000Z 字数 3635 阅读 1631

教你一步一步动手写自己的AFNwetworking(一)

博客文章


前言:网上有很多通过直接查看AFNwetworking(以下省称AFN)源代码来阐述其实现原理的文章,但是本系列文章希望从另外一个角度来解读AFN, 即通过一步一步动手实现自己的AFN,从最简单的基本功能到最后的完善。

假设我们iOS圈没有AFNwetworking、ASIHTTPRequest等网络请求库,你会动手从零开始写出一个自己的网络请求库吗?

参考AFNwetworking3.x为例,此库实现主要功能有:

  1. 发送普通Http请求(主要是get/post)
  2. 上传操作
  3. 下载操作
  4. 网络监听
    ...

第一步:封装(发送普通Http请求)功能

万丈高楼从低起,我们从封装发送普通Http请求这个最简单的功能开始。
其中我们最常用的功能是发送普通Http请求,我们首先看看AFN发送get、post的基本使用:

  1. // 发送get请求
  2. AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
  3. [manager GET:@"http://localhost" parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {
  4. // 处理网络的进度
  5. } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
  6. // 请求成功的回调 responseObject默认是json数据
  7. } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
  8. // 请求失败的回调
  9. }];
  1. // 发送post请求
  2. AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
  3. // 设置请求参数
  4. NSMutableDictionary *param = [NSMutableDictionary dictionary];
  5. param[@"name"] = @"chenbinghua";
  6. [manager GET:@"http://localhost" parameters:nil progress:^(NSProgress * _Nonnull downloadProgress) {
  7. // 处理网络的进度
  8. } success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
  9. // 请求成功的回调 responseObject默认是json数据
  10. } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
  11. // 请求失败的回调
  12. }];

NSURLSession

在AFNAFNwetworking2.x的时候,发送请求是用NSURLConnection。到了后来,用了功能更为牛逼的NSURLSession
以下是NSURLSession发送get、post请求的方法:

目标代码

  1. #import "MyHTTPSessionManager.h"
  2. // 请求成功的block
  3. typedef void (^MyHTTPSessionSuccessBlock)(NSURLSessionDataTask *task, id responseObject);
  4. // 请求失败的block
  5. typedef void (^MyHTTPSessionFailureBlock)(NSURLSessionDataTask *task, NSError *error);
  6. #pragma mark -
  7. @interface MyHTTPSessionManager()<NSURLSessionDataDelegate>
  8. @property (nonatomic, copy) MyHTTPSessionSuccessBlock success;
  9. @property (nonatomic, copy) MyHTTPSessionFailureBlock failure;
  10. @property (nonatomic,strong) id responseObject;
  11. @end
  12. @implementation MyHTTPSessionManager
  13. - (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
  14. URLString:(NSString *)URLString
  15. parameters:(NSDictionary *)parameters
  16. success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
  17. failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
  18. {
  19. NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[[NSOperationQueue alloc] init]];
  20. self.success = success;
  21. self.failure = failure;
  22. // 2.创建请求
  23. NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:URLString]];
  24. request.HTTPMethod = method; // 请求方法
  25. request.HTTPBody = [[self httpBodyWithDictionary:parameters] dataUsingEncoding:NSUTF8StringEncoding]; // 请求体
  26. // 创建任务
  27. NSURLSessionDataTask *task = [session dataTaskWithRequest:request];
  28. // 启动任务
  29. [task resume];
  30. return task;
  31. }
  32. - (NSString *)httpBodyWithDictionary:(NSDictionary *)dic{
  33. NSMutableString *bodyString = [NSMutableString string];
  34. for (NSString *key in dic) {
  35. [bodyString appendFormat:@"%@=%@&",key,dic[key]];
  36. }
  37. return bodyString;
  38. }
  39. #pragma mark - <NSURLSessionDataDelegate>
  40. /**
  41. * 1.接收到服务器的响应
  42. */
  43. - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
  44. {
  45. // 允许处理服务器的响应,才会继续接收服务器返回的数据,只能放在最后
  46. completionHandler(NSURLSessionResponseAllow);
  47. }
  48. /**
  49. * 2.接收到服务器的数据(可能会被调用多次)
  50. */
  51. - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
  52. {
  53. self.responseObject = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
  54. }
  55. /**
  56. * 3.请求成功或者失败(如果失败,error有值)
  57. */
  58. - (void)URLSession:(NSURLSession *)session task:(NSURLSessionDataTask *)task didCompleteWithError:(NSError *)error
  59. {
  60. if (error) {
  61. if (self.failure) {
  62. self.failure(task,error);
  63. }
  64. }else{
  65. if (self.success) {
  66. self.success(task,self.responseObject);
  67. }
  68. }
  69. }
  70. @end

总结

参考文章

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注