一、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. C语言字符串大小写转换_只愿与一人十指紧扣_新浪博客
  2. java -version cmd_java如何运行步骤cmd?Java执行cmd命令方法有哪些?
  3. About LOCAL_PRIVATE_PLATFORM_APIS in Android.mk
  4. 桂林哪些职校可以学计算机,桂林市有几个中等职业学校
  5. 阅读微信支付demo收获
  6. 从零学习SwinTransformer
  7. 多路 IO 转接 :select 函数
  8. (网页)parseFloat在工作中遇到的错误
  9. 设计模式适配器模式_21世纪的设计模式:适配器模式
  10. Javascript中的翻转器
  11. 车场系统服务器内存莫名急速下降,宝德工控机在停车场监控系统的解决方案
  12. 计算机专业论文周记20篇,毕业论文工作周记6篇
  13. EasyNVR无插件网页摄像机直播流媒体服务器对接海康8700平台视频出现RTSP视频无法接入的问题解决
  14. 2021哈工程计算机考研科目,2021考研大纲:哈尔滨工程大学计算机专业基础综合2021年硕士研究生自命题考试大纲...
  15. matlab bar 填充花纹,[转载]Matlab绘制柱状图采用不同图案填充
  16. vim - 之快速删除指定符号的内容
  17. android电视不能root权限,智能电视如何刷机获取root权限,当贝市场推荐四种方法!...
  18. Wordpress关闭所有评论
  19. UNIAPP手写签名
  20. HashMap线程安全问题详细解析

热门文章

  1. 中国科学技术大学高新园,最大校区投入使用!
  2. oracle---实例+进程优化
  3. 使用jQuery怼一个很low的QQ农场 | (练习+自娱自乐)
  4. 怎么给电脑加内存?给笔记本加内存的详细步骤及相关注意事项。
  5. 网站设置隐藏友情链接的方法!
  6. Array的内置方法api
  7. 弘辽科技:淘宝直通车非标品测图的技巧有哪些?
  8. MyBatis 框架基础
  9. 日立笔记本硬盘7k500型号解释
  10. 虚拟机IP与电脑热点IP冲突解决办法