AFN原理&& AFN如何使用RunLoop来实现的:

让你介绍一下AFN源码的理解,首先要说说封装里面主要做了那些重要的事情,有那些重要的类(XY题)

一、AFN的实现步骤:

    NSString * requestURL = @"http://119.254.98.136/api/v1/web/homepage";

//    AFHTTPSessionManager * manager =[[AFHTTPSessionManager alloc] init];
AFHTTPSessionManager * manager =[AFHTTPSessionManager manager];
[manager GET:requestURL parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSLog(@"请求成功了!");
NSLog(@"%@",responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"请求失败了!");
}];

1、GET,或者POST等方法调用抽象的请求方法,指明相应的请求参数,(类似全能初始化方法的作用一下,最后不管多少个初始化参数的方法,都最后是调用了全能初始化方法),不管是什么形式的数据请求,最后是调用了全能数据请求的方法。指明数据请求的方式以及全能的参数。

- (NSURLSessionDataTask *)GET:(NSString *)URLString
parameters:(id)parameters
progress:(void (^)(NSProgress * _Nonnull))downloadProgress
success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
{ NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"GET"
URLString:URLString
parameters:parameters
uploadProgress:nil
downloadProgress:downloadProgress
success:success
failure:failure]; [dataTask resume]; return dataTask;
}

2、对请求进行序列化,如果序列化失败,就直接执行了failure block,否则继续3

- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
URLString:(NSString *)URLString
parameters:(id)parameters
uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgress
downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgress
success:(void (^)(NSURLSessionDataTask *, id))success
failure:(void (^)(NSURLSessionDataTask *, NSError *))failure
{
NSError *serializationError = nil;
NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError];
if (serializationError) {
if (failure) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu"
dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
failure(nil, serializationError);
});
#pragma clang diagnostic pop
} return nil;
} __block NSURLSessionDataTask *dataTask = nil;
dataTask = [self dataTaskWithRequest:request
uploadProgress:uploadProgress
downloadProgress:downloadProgress
completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
if (error) {
if (failure) {
failure(dataTask, error);
}
} else {
if (success) {
success(dataTask, responseObject);
}
}
}]; return dataTask;
}

3、为每一个NSURLSessionDataTask的dataTask增加代理

- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request
uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressBlock
downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlock
completionHandler:(nullable void (^)(NSURLResponse *response, id _Nullable responseObject, NSError * _Nullable error))completionHandler { __block NSURLSessionDataTask *dataTask = nil;
url_session_manager_create_task_safely(^{
dataTask = [self.session dataTaskWithRequest:request];
}); [self addDelegateForDataTask:dataTask uploadProgress:uploadProgressBlock downloadProgress:downloadProgressBlock completionHandler:completionHandler]; return dataTask;
}

4、对每一个NSURLSessionDataTask的dataTask增加代理的具体实现,对dataTask设置请求之后的回调Delegate和处理block

- (void)addDelegateForDataTask:(NSURLSessionDataTask *)dataTask
uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgressBlock
downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgressBlock
completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler
{
AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] init];
delegate.manager = self;
delegate.completionHandler = completionHandler; dataTask.taskDescription = self.taskDescriptionForSessionTasks;
[self setDelegate:delegate forTask:dataTask]; delegate.uploadProgressBlock = uploadProgressBlock;
delegate.downloadProgressBlock = downloadProgressBlock;
}
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wgnu"
dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
failure(nil, serializationError);
});
#pragma clang diagnostic pop

表示在这个区间里忽略一些特定的clang的编译警告,因为AFNetworking作为一个库被其他项目引用,所以不能全局忽略clang的一些警告,只能在有需要的时候局部这样做,作者喜欢用?:符号,所以经常见忽略-Wgnu警告的写法

NSURLConnection 是 Foundation URL 加载系统的基石。一个 NSURLConnection 异步地加载一个 NSURLRequest 对象,调用 delegate 的 NSURLResponse / NSHTTPURLResponse 方法,其 NSData 被发送到服务器或从服务器读取;delegate 还可用来处理 NSURLAuthenticationChallenge、重定向响应、或是决定 NSCachedURLResponse 如何存储在共享的 NSURLCache 上。

NSOperation 是抽象类,模拟单个计算单元,有状态、优先级、依赖等功能,可以取消。

AFURLConnectionOperation将两者结合, 作为 NSOperation 的子类,遵循 NSURLConnectionDelegate 的方法,可以从头到尾监视请求的状态,并储存请求、响应、响应数据等中间状态。

创建 AFURLConnectionOperation 并把它安排进 NSOperationQueue,通过设置 NSOperation 的新属性 completionBlock,指定操作完成时如何处理 response 和 response data(或是请求过程中遇到的错误)。

AFNetworking 3.0 实现完全基于NSURLSessionTask进行封装,NSURLSessionTask 是苹果在iOS7 推出的网络请求api。AF支持https,网络数据请求,文件上传,文件下载,监听手机网络状态。AFHttpSessionManager 继承 AFURLSessionManager 对网络请求进行管理,使用AFURLRequestSerialization 对网络请求进行封装,使用AFURLReponseSerialization 响应体进行处理,使用AFSecurityPolicy 对服务器证书进行校验。支持https协议,支持本地证书和服务器证书进行对比验证,AF要求ios7或以上系统。AF数据传递主要使用block 和 notifacation的方式。

使用详解

AFURLSessionManager 使用方法

1、请求服务器数据

2、上传数据

3、多线程下载数据

AFHttpSessionManager 使用方法

1、post

2、get

3、上传

AFSecurityPolicy

服务器和客户端都生成相应的证书之后,iOS项目将服务器端的证书保存导入到项目中。接着AFN根据项目中的服务器的证书来进行验证。

AFSecurityPolicy对服务器的验证,保证访问服务器的安全性。(这里牵涉到Https和Http的不同,以及不同的验证方式,请求有何不同。)

证书的验证模式 AFSecurityPolicy *securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate];

  • AFSSLPinningModeNone

不做任何验证,只要服务器返回了证书就通过

  • AFSSLPinningModePublicKey

只验证公钥部分,只要公钥部分一致就验证通过,如图所示,红色框起来的部分只要一致就通过

  • AFSSLPinningModeCertificate

除了公钥外,其他能容也要一致才能通过验证。

AFURLSessionManager

AFURLSessionManager管理所有的请求,session 设置了NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate 实现证书合法性校验,数据传输进度检测,数据请求成功或失败的回调。

使用runtime 用af_supend 替换 suspend,用af_resume 替换了resume 当调用这两个方法的时候往上层发送通知AFNetworkingTaskDidSuspendNotification AFNetworkingTaskDidResumeNotification

AFNetworking 3.0 使用详解 和 源码解析实现原理的更多相关文章

  1. 详解HashMap源码解析(下)

    上文详解HashMap源码解析(上)介绍了HashMap整体介绍了一下数据结构,主要属性字段,获取数组的索引下标,以及几个构造方法.本文重点讲解元素的添加.查找.扩容等主要方法. 添加元素 put(K ...

  2. SpringBoot之DispatcherServlet详解及源码解析

    在使用SpringBoot之后,我们表面上已经无法直接看到DispatcherServlet的使用了.本篇文章,带大家从最初DispatcherServlet的使用开始到SpringBoot源码中Di ...

  3. cas客户端流程详解(源码解析)--单点登录

    博主之前一直使用了cas客户端进行用户的单点登录操作,决定进行源码分析来看cas的整个流程,以便以后出现了问题还不知道是什么原因导致的 cas主要的形式就是通过过滤器的形式来实现的,来,贴上示例配置: ...

  4. 六张图详解LinkedList 源码解析

    LinkedList 底层基于链表实现,增删不需要移动数据,所以效率很高.但是查询和修改数据的效率低,不能像数组那样根据下标快速的定位到数据,需要一个一个遍历数据. 基本结构 LinkedList 是 ...

  5. 详解HashMap源码解析(上)

    jdk版本:1.8 数据结构: HashMap的底层主要基于数组+链表/红黑树实现,数组优点就是查询块,HashMap通过计算hash码获取到数组的下标来查询数据.同样也可以通过hash码得到数组下标 ...

  6. CharacterEncodingFilter详解及源码解析

    字符编码过滤器  (Spring框架对字符编码的处理) 基于函数回调,对所有请求起作用,只在容器初始化时调用一次,依赖于servlet容器. web.xml配置文件 <filter> &l ...

  7. Ros学习——移动机器人Ros导航详解及源码解析

    1 执行过程 1.运行仿真机器人fake_turtlebot.launch:加载机器人模型——启动机器人仿真器——发布机器人状态 2.运行amcl节点fake_amcl.launch:加载地图节点ma ...

  8. 详解ConCurrentHashMap源码(jdk1.8)

    ConCurrentHashMap是一个支持高并发集合,常用的集合之一,在jdk1.8中ConCurrentHashMap的结构和操作和HashMap都很类似: 数据结构基于数组+链表/红黑树. ge ...

  9. 基于双向BiLstm神经网络的中文分词详解及源码

    基于双向BiLstm神经网络的中文分词详解及源码 基于双向BiLstm神经网络的中文分词详解及源码 1 标注序列 2 训练网络 3 Viterbi算法求解最优路径 4 keras代码讲解 最后 源代码 ...

随机推荐

  1. [护网杯2018] easy_laravel

    前言 题目环境 buuoj 上的复现,和原版的题目不是完全一样.原题使用的是 nginx + mysql 而 buuoj 上的是 apache + sqlite composer 这是在 PHP5.3 ...

  2. 原子类的ABA问题

    原子类AtomicInteger的ABA问题 连环套路 从AtomicInteger引出下面的问题 CAS -> Unsafe -> CAS底层思想 -> ABA -> 原子引 ...

  3. .Net Core主机配置

    Host:(主机)负责web应用程序的启用和生成期管理,配置服务器和请求处理管道. 主机配置日志,依赖注入关系,实际上是一个封装了应用资源的对象. 创建主机生成器-〉配置主机-〉创建主机-〉运行主机. ...

  4. MySql的数据库方言问题

    在使用hibernate将po(一般对象类)转化为数据库表时,如果mysql的版本为5.0之前的,则方言写为:<property name="dialect">org. ...

  5. testlink配置修改

    1.      Read/write permissions报错 问题: Checking if  /var/testlink/logs/ directory exists [S] </B< ...

  6. DEDE Fatal error: Maximum execution time of 30 seconds exceeded 致命 错误: 最大的 执行 时间 为 30 秒

    刚安的DEDE    5.7 -SP1-GBK的  为何一登录后台点任何链接都显示超过30秒  后台假死 网上搜的方法一般都是更改执行时间上限,其目的是为了解决一些大的数据,真的需要30秒以上的执行时 ...

  7. (四)PL/SQL运算符

    运算符是一个符号,告诉编译器执行特定的数学或逻辑操作. PL/SQL语言有丰富的内置运算符,运算符提供的以下几种类型: 1.算术运算符 2.关系运算符 3.比较运算符 4.逻辑运算符 5.字符串运算符 ...

  8. spark系列-2、Spark 核心数据结构:弹性分布式数据集 RDD

    一.RDD(弹性分布式数据集) RDD 是 Spark 最核心的数据结构,RDD(Resilient Distributed Dataset)全称为弹性分布式数据集,是 Spark 对数据的核心抽象, ...

  9. json序列化字符串后,配置枚举类型显示数值而不是名称

    2019独角兽企业重金招聘Python工程师标准>>> 经常有这么一个需求,实体类里面用到枚举常量,但序列化成json字符串时.默认并不是我想要的值,而是名称,如下 类 @Data ...

  10. servlet温故知新

    重新学习了一遍servlet-api的文档,做一些记录. 有道云的笔记直接复制到博客上格式会乱,因此直接放上有道云的链接:http://note.youdao.com/noteshare?id=915 ...