AFNetworking 3.0 使用详解 和 源码解析实现原理
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 使用详解 和 源码解析实现原理的更多相关文章
- 详解HashMap源码解析(下)
上文详解HashMap源码解析(上)介绍了HashMap整体介绍了一下数据结构,主要属性字段,获取数组的索引下标,以及几个构造方法.本文重点讲解元素的添加.查找.扩容等主要方法. 添加元素 put(K ...
- SpringBoot之DispatcherServlet详解及源码解析
在使用SpringBoot之后,我们表面上已经无法直接看到DispatcherServlet的使用了.本篇文章,带大家从最初DispatcherServlet的使用开始到SpringBoot源码中Di ...
- cas客户端流程详解(源码解析)--单点登录
博主之前一直使用了cas客户端进行用户的单点登录操作,决定进行源码分析来看cas的整个流程,以便以后出现了问题还不知道是什么原因导致的 cas主要的形式就是通过过滤器的形式来实现的,来,贴上示例配置: ...
- 六张图详解LinkedList 源码解析
LinkedList 底层基于链表实现,增删不需要移动数据,所以效率很高.但是查询和修改数据的效率低,不能像数组那样根据下标快速的定位到数据,需要一个一个遍历数据. 基本结构 LinkedList 是 ...
- 详解HashMap源码解析(上)
jdk版本:1.8 数据结构: HashMap的底层主要基于数组+链表/红黑树实现,数组优点就是查询块,HashMap通过计算hash码获取到数组的下标来查询数据.同样也可以通过hash码得到数组下标 ...
- CharacterEncodingFilter详解及源码解析
字符编码过滤器 (Spring框架对字符编码的处理) 基于函数回调,对所有请求起作用,只在容器初始化时调用一次,依赖于servlet容器. web.xml配置文件 <filter> &l ...
- Ros学习——移动机器人Ros导航详解及源码解析
1 执行过程 1.运行仿真机器人fake_turtlebot.launch:加载机器人模型——启动机器人仿真器——发布机器人状态 2.运行amcl节点fake_amcl.launch:加载地图节点ma ...
- 详解ConCurrentHashMap源码(jdk1.8)
ConCurrentHashMap是一个支持高并发集合,常用的集合之一,在jdk1.8中ConCurrentHashMap的结构和操作和HashMap都很类似: 数据结构基于数组+链表/红黑树. ge ...
- 基于双向BiLstm神经网络的中文分词详解及源码
基于双向BiLstm神经网络的中文分词详解及源码 基于双向BiLstm神经网络的中文分词详解及源码 1 标注序列 2 训练网络 3 Viterbi算法求解最优路径 4 keras代码讲解 最后 源代码 ...
随机推荐
- 尝试用Vue.js开发网页小游戏的过程
准备 首先去官方下载并安装VSCODE,下载地址 https://code.visualstudio.com/.安装后打开会发现是英文版的,需要去安装插件来汉化.具体是在扩展插件搜索chinese,选 ...
- Java 排序算法-冒泡排序及其优化
Java 排序算法-冒泡排序及其优化 什么是冒泡排序 基本写法 优化后写法 终极版本 源码及测试 什么是冒泡排序 这里引用一下百度百科上的定义: 冒泡排序(Bubble Sort),是一种计算机科学领 ...
- Nginx知多少系列之(十四)Linux下.NET Core项目Nginx+Keepalived高可用(主从模式)
目录 1.前言 2.安装 3.配置文件详解 4.工作原理 5.Linux下托管.NET Core项目 6.Linux下.NET Core项目负载均衡 7.负载均衡策略 8.加权轮询(round rob ...
- 微信小程序填坑---小程序支付
因为公司刚刚重新做了网站,所以也吧公众号和小程序提上了日程,在公众号里面没有什么问题,直接按照官方文档进行代码编写.调试,然后就解决了公众号内支付的问题. 因为小程序提供了<webview> ...
- sqlilabs less18-22 HTTP头的注入
less18 user-agent的注入 源码分析: check_input对name,password进行了过滤 function check_input($value) { if(!empty($ ...
- PHP 使用try catch,捕获异常
<?php header('Content-type:text/html;charset=utf-8'); $a = 1; $b = 2; try { / ...
- Windows 版本 Enterprise、Ultimate、Home、Professional
关于Windows 的安装光盘版本很多种,很多人不知道选择哪些. Ultimate 旗舰版,VISTA开始有了这个级别,是最全最高级的,一般程序开发的电脑,玩游戏的电脑,建议用它,不过对配置稍有一些要 ...
- Scala教程之:Enumeration
Enumeration应该算是程序语言里面比较通用的一个类型,在scala中也存在这样的类型, 我们看下Enumeration的定义: abstract class Enumeration (init ...
- 全网最简单明了的MySQL连接Eclipse方法(JDBC详细安装方式及简单操作)2020新版
Step 1 你得有Eclipse 没有出门右拐,我教不了你. Step 2 你得有Mysql MySQL的详细安装过程,我在另一篇博客中给出.戳我 Step 3 安装JDBC 可以去官网下,如果用的 ...
- C++课程设计,12306模拟写起来就是这么粗暴
这篇文章很详细,也很多希望可以好好看看!看完C++稳过! 一.12306应该具备那些功能 1.查询(一个月以内的): 1.查车票:出发地+目的地+出发时间->显示经过两站车票信息 (余票,车次信 ...