一、AFURLSessionManager

网络请求的核心类,主要作用有以下几点:

1、线程安全的创建NSURLSession,并实现NSURLSessionDelegate

2、设置responseSerializer(用于返回数据的解析,默认AFJSONResponseSerializer

设置securityPolicy(用于SSL证书,HTTPS访问安全管理)

设置completionQueue(请求完成返回数据时的队列,不设置默认回到主线程队列)

设置completionGroup(请求完成返回数据时的队列组,不设置会使用默认值)

设置reachabilityManager(用于网络状况的监控)

3、生成各类NSURLSessionTask,以及设置各类Task的回调Block。

NSURLSessionDataTask、NSURLSessionUploadTask、NSURLSessionDownloadTask

4、管理AFURLSessionManagerTaskDelegate,根据Task标识,把NSURLSessionDelegate

回调分发到具体的AFURLSessionManagerTaskDelegate对象中

二、AFHTTPSessionManager

是AFURLSessionManager子类,除了父类功能外,还有以下作用:

1、设置requestSerializer

2、根据不同请求方式生成NSURLSessionDataTask

三、AFURLRequestSerialization

是生成NSURLRequest的协议,主要针对AFHTTPSessionManager的requestSerializer

AFURLRequestSerialization协议实现类为:AFHTTPRequestSerializer,除了帮我们生成

NSURLRequest外,还可以设置stringEncoding、allowsCellularAccess、cachePolicy、

HTTPRequestHeaders等一些请求相关的参数。

AFHTTPRequestSerializer有2个子类(主要用于不同的`Content-Type`):

AFJSONRequestSerializer(application/json)

AFPropertyListRequestSerializer(application/x-plist)

在处理multipart/form-data方式时,提供了方法:

- (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)methodURLString:(NSString *)URLStringparameters:(nullable NSDictionary <NSString *, id> *)parametersconstructingBodyWithBlock:(nullable void (^)(id <AFMultipartFormData> formData))blockerror:(NSError * _Nullable __autoreleasing *)error;

在constructingBodyWithBlock中提供了实现AFMultipartFormData协议的类用于添加参数

AFMultipartFormData真正的实现类是AFStreamingMultipartFormData

四、AFURLResponseSerialization

是解析Response的协议,实现类为:AFHTTPResponseSerializer

AFHTTPResponseSerializer有以下几个子类(用于解析不同的MIMEType):

AFJSONResponseSerializer(json解析)

AFXMLParserResponseSerializer(xml解析,返回NSXMLParser)

AFXMLDocumentResponseSerializer(xml解析,返回NSXMLDocument)

AFPropertyListResponseSerializer(plist解析)

AFImageResponseSerializer(图片解析)

AFCompoundResponseSerializer(组合解析,可以添加多个上面类,根据顺序解析)

五、AFURLSessionManagerTaskDelegate

真正的NSURLSessionDelegate实现类,用于管理Task的上传下载进度,完成回调等

六、完整的网络请求流程

1、准备工作。初始化AFHTTPSessionManager,并根据业务设置requestSerializer、

responseSerializer、baseUrl等

2、创建Task,以自定义NSURLSessionDataTask为例:

- (nullable NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)methodURLString:(NSString *)URLStringparameters:(nullable id)parametersheaders:(nullable NSDictionary <NSString *, NSString *> *)headersuploadProgress:(nullable void (^)(NSProgress *uploadProgress))uploadProgressdownloadProgress:(nullable void (^)(NSProgress *downloadProgress))downloadProgresssuccess:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))successfailure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;

首页会根据我们设置的requestSerializer生成NSMutableURLRequest:

NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError];

设置请求头:

for (NSString *headerField in headers.keyEnumerator) {[request setValue:headers[headerField] forHTTPHeaderField:headerField];
}

如果requestSerializer报错,就结束流程,从completionQueue回调出去,

如果requestSerializer成功,开始生成NSURLSessionDataTask:

    __block NSURLSessionDataTask *dataTask = nil;dataTask = [self dataTaskWithRequest:requestuploadProgress:uploadProgressdownloadProgress:downloadProgresscompletionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {if (error) {if (failure) {failure(dataTask, error);}} else {if (success) {success(dataTask, responseObject);}}}];

我们跟着生成的方法点进去看到,通过AFHTTPSessionManager.session生成Task,并且

创建Task的AFURLSessionManagerTaskDelegate和回调参数,同时根据Task的标识存储

Delegate到mutableTaskDelegatesKeyedByTaskIdentifier字典中

NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:request];[self addDelegateForDataTask:dataTask uploadProgress:uploadProgressBlock downloadProgress:downloadProgressBlock completionHandler:completionHandler];
- (void)addDelegateForDataTask:(NSURLSessionDataTask *)dataTaskuploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressBlockdownloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlockcompletionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
{AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] initWithTask:dataTask];delegate.manager = self;delegate.completionHandler = completionHandler;dataTask.taskDescription = self.taskDescriptionForSessionTasks;[self setDelegate:delegate forTask:dataTask];delegate.uploadProgressBlock = uploadProgressBlock;delegate.downloadProgressBlock = downloadProgressBlock;
}
- (void)setDelegate:(AFURLSessionManagerTaskDelegate *)delegateforTask:(NSURLSessionTask *)task
{NSParameterAssert(task);NSParameterAssert(delegate);[self.lock lock];self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)] = delegate;[self addNotificationObserverForTask:task];[self.lock unlock];
}

3、启动Task,使用resume方法。而后通过NSURLSessionDelegate监听网络请求过程。我们

可以看到AFURLSessionManager实现的NSURLSessionDelegate方法中,首先根据task

标识获取对应的AFURLSessionManagerTaskDelegate,然后分发事件至具体的Delegate

类中。我们以didCompleteWithError回调看:

- (void)URLSession:(NSURLSession *)sessiontask:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error
{AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:task];// delegate may be nil when completing a task in the backgroundif (delegate) {[delegate URLSession:session task:task didCompleteWithError:error];[self removeDelegateForTask:task];}if (self.taskDidComplete) {self.taskDidComplete(session, task, error);}
}

4、请求完成回调处理,实际是在AFURLSessionManagerTaskDelegate中实现的,通过阅读

代码实现可以看出如果请求出现错误,就回调到completionHandler,如果未出现错误,

首先获取manager的responseSerializer去解析返回内容,然后再回调出去

- (void)URLSession:(__unused NSURLSession *)sessiontask:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error
{error = objc_getAssociatedObject(task, AuthenticationChallengeErrorKey) ?: error;__strong AFURLSessionManager *manager = self.manager;__block id responseObject = nil;NSMutableDictionary *userInfo = [NSMutableDictionary dictionary];userInfo[AFNetworkingTaskDidCompleteResponseSerializerKey] = manager.responseSerializer;//Performance Improvement from #2672NSData *data = nil;if (self.mutableData) {data = [self.mutableData copy];//We no longer need the reference, so nil it out to gain back some memory.self.mutableData = nil;}#if AF_CAN_USE_AT_AVAILABLE && AF_CAN_INCLUDE_SESSION_TASK_METRICSif (@available(iOS 10, macOS 10.12, watchOS 3, tvOS 10, *)) {if (self.sessionTaskMetrics) {userInfo[AFNetworkingTaskDidCompleteSessionTaskMetrics] = self.sessionTaskMetrics;}}
#endifif (self.downloadFileURL) {userInfo[AFNetworkingTaskDidCompleteAssetPathKey] = self.downloadFileURL;} else if (data) {userInfo[AFNetworkingTaskDidCompleteResponseDataKey] = data;}if (error) {userInfo[AFNetworkingTaskDidCompleteErrorKey] = error;dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{if (self.completionHandler) {self.completionHandler(task.response, responseObject, error);}dispatch_async(dispatch_get_main_queue(), ^{[[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task userInfo:userInfo];});});} else {dispatch_async(url_session_manager_processing_queue(), ^{NSError *serializationError = nil;responseObject = [manager.responseSerializer responseObjectForResponse:task.response data:data error:&serializationError];if (self.downloadFileURL) {responseObject = self.downloadFileURL;}if (responseObject) {userInfo[AFNetworkingTaskDidCompleteSerializedResponseKey] = responseObject;}if (serializationError) {userInfo[AFNetworkingTaskDidCompleteErrorKey] = serializationError;}dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{if (self.completionHandler) {self.completionHandler(task.response, responseObject, serializationError);}dispatch_async(dispatch_get_main_queue(), ^{[[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task userInfo:userInfo];});});});}
}

AFNetworking网络请求详解相关推荐

  1. afn访问本地html,Swift利用AFN实现封装网络请求详解

    前言 相信大家都知道,我们一般在一个项目中,网络请求都封装成一个单例,以确保整个项目的网络请求 Session 是同一个. 单例模式定义:一个类有且仅有一个实例,并且自行实例化向整个系统提供,下面话不 ...

  2. Android 网络请求详解

    我们知道大多数的 Android 应用程序都是通过和服务器进行交互来获取数据的.如果使用 HTTP 协议来发送和接收网络数据,就免不了使用 HttpURLConnection 和 HttpClient ...

  3. afn原理 ios_iOS AFNetworking网络框架详解

    导语: 众所周知,AFNetworking是目前IOS开发中非常受欢迎的第三方网络通信类库,同时AFNetworking对苹果官方NSURLConnection和NSURLSession进行了封装,使 ...

  4. 用netstat查看网络状态详解

    --用netstat查看网络状态详解 -----------------------------2014/06/11 一.Linux服务器上11种网络连接状态:                     ...

  5. nbns协议_网络协议详解1 - NBNS

    NetBIOS 简介 NetBIOS,Network Basic Input/Output System的缩写,一般指用于局域网通信的一套API,相关RFC文档包括 RFC 1001, RFC 100 ...

  6. Linux网络编程---详解TCP

    Linux网络编程---详解TCP的三次握手和四次挥手_shanghx_123的博客-CSDN博客_tcp的协议数据单元被称为 TCP协议详解(TCP报文.三次握手.四次挥手.TIME_WAIT状态. ...

  7. JavaEE基础(03):Http请求详解,握手挥手流程简介

    本文源码:GitHub·点这里 || GitEE·点这里 一.Http协议简介 1.概念说明 HTTP超文本传输协议,是用于从万维网服务器传输超文本到本地浏览器的传送协议,基于TCP/IP通信协议来传 ...

  8. 网络知识详解之:网络攻击与安全防护

    网络知识详解之:网络攻击与安全防护 计算机网络相关知识体系详解 网络知识详解之:TCP连接原理详解 网络知识详解之:HTTP协议基础 网络知识详解之:HTTPS通信原理剖析(对称.非对称加密.数字签名 ...

  9. 趣谈网络协议-第二模块-底层网络知识详解:4陌生的数据中心2CDN和数据中心

    趣谈网络协议-第二模块-底层网络知识详解:4陌生的数据中心2CDN和数据中心 1:CDN:你去小卖部取过快递么? 使用"中间仓库"来优化 网络中的"就近配送" ...

最新文章

  1. 软件架构设计 温昱著 - 读书笔记
  2. 误用.Net Redis客户端工具CSRedisCore,自己挖坑自己填
  3. 现代交换技术学习笔记001
  4. java里面的 |运算符_Java 中 | ^ 运算符的简单使用
  5. map类的erase方法的在Linux与Windows中的差异
  6. 推荐系统(3)-协同过滤2-矩阵分解算法
  7. 【Python】Python3编码规范
  8. Linux创建软连接
  9. Mac OS X10.11下CocoaPods的安装过程
  10. 中值滤波器的matlab实现
  11. c语言炒股软件公式,股票软件怎么使用指标选股公式
  12. 聊一聊,android程序员前景如何
  13. MySql 操作时间
  14. 研究生毕业论文如何选题
  15. 猜数字(Bulls and Cows)游戏
  16. excel标题行列浮动显示/冻结窗口
  17. 小高不太行之前端--JSON
  18. 参加《前沿科学国际研讨会》的世界著名学者简介
  19. 长续航高性价比,轻松畅享好音质 ——索尼长续航颈挂式无线耳机WI-C100活力发布
  20. CF专题(长安大学)

热门文章

  1. 【算法】局部敏感哈希 LSH 的 Python 实现
  2. 想成为真正的网游研发员吗,从这开始吧
  3. python实现手机通讯录_Python实现命令行通讯录
  4. html计算数学表达式,如何使用MathCalc在JavaScript中实现基本的数学表达式计算器...
  5. iOS开发-支付宝手势解锁实现展示
  6. CH395: TCP/IP网络协议栈芯片,让单片机轻松联网
  7. Traceroute
  8. 一点排位就安全异常退出_腾讯游戏信用 影响CF排位赛
  9. websocket java详解_WebSocket详解
  10. java生成与解析二维码 支持插入图片与文字