AFNetworking封装思路简析
http://blog.csdn.net/qq_34101611/article/details/51698473
一、AFNetworking的发展
1. AFN 1.0版本
AFN 的基础部分是 AFURLConnectionOperation,一个 NSOperation 子类,实现了 基于NSURLConnection 相关的delegate+blocks,网络部分是由 NSURLConnection 完成,然后利用 NSOperation 的 state(isReady→isExecuting→isFinished) 变化来进行网络控制。网络请求是在一个指定的线程(networkRequestThread)完成。
AFURLConnectionOperation是一个很纯粹的网络请求 operation,可以对他进行 start/cancel/pause/resume 操作,可以获取对应的 NSURLRequest 和 NSURLResponse 数据。提供了 uploadPress 和downloadProgress 以方便其他使用。
AFHTTPRequestOperation是 AFURLConnectionOperation 的子类,针对 HTTP+HTTPS 协议做了一层封装,比如statusCode、Content-Type 等,添加了请求成功和失败的回调 block,提供了addAcceptableContentTypes: 以方便上层使用。
2. AFN 2.0版本
NSURLSession
NSURLSession 是 iOS 7 新引入的用于替代 NSURLConnection 的类。NSURLConnection 并没有被弃用,今后一段时间应该也不会(事实上最终还是被弃用了)。它们有一些重叠,AFNetworking提供了更高层次的抽象,并最大程度扩展了它的实用性。 模块化
对于AFNetworking的主要批评之一是笨重。虽然它的构架使在类的层面上是模块化的,但它的包装并不允许选择独立的一些功能。随着时间的推移,AFHTTPClient 尤其变得不堪重负。 在AFNetworking 2.0 中,你可以挑选并通过 CocoaPods subspecs 选择你所需要的组件
3. AFN 3.0版本
AFN 3.0+弃用NSURLConnection,只提供NSURLSession的支持。
二、NSURLSession简单实用
1. 普通的GET/POST请求
- 获取URL
- 创建request,修改请求方法、请求体(GET请求不需要)
- 获取全局Session
- 发起任务(进行反序列化)
- 结束任务
2. 上传请求
NSData *imageData = UIImagePNGRepresentation(image);
//1.NSURL
NSURL *url = [NSURL URLWithString:@"http://localhost/post/upload.php"];
//2.NSMutableURLRequest
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
//2.1 改请求方法
request.HTTPMethod = @"POST";
//2.2.设置请求头,boundary 这个就是一个分隔符,可以随便写, 只要不是中文
NSString *contentTypevalue = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", kBoundaryUpload];
[request setValue:contentTypevalue forHTTPHeaderField:@"Content-Type"];
//NSURLSession不要把上传的文件放入请求体中,应该放在NSURLSession的方法中
NSData *fileData = [self formDataWithFileData:imageData serverFieldName:@"userfile" fileSaveName:@"abc.png"];
//3.获取系统提供的NSURLSession
NSURLSession *globalSession = [NSURLSession sharedSession];
//4.由session发起上传任务
[[globalSession uploadTaskWithRequest:request fromData:fileData completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
//4.反序列化
if (error==nil && data.length>0) {
id result =[NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
NSLog(@"login-----%@",result);
}
}] resume];
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- (NSData *)formDataWithFileData:(NSData *)fileData serverFieldName:(NSString *)serverFieldName fileSaveName:(NSString *)fileSaveName{
//1.NSMutableData
NSMutableData *dataM = [NSMutableData data];
/**
-----------------------------11454065798049615451989194362
Content-Disposition: form-data; name="userfile"; filename="abc.txt"
Content-Type: application/octet-stream
111222333
-----------------------------11454065798049615451989194362--
*/
//2.拼接头
NSMutableString *headerString = [NSMutableString string];
//2.1 拼接第一行
[headerString appendFormat:@"--%@\r\n",kBoundaryUpload];
//2.1 拼接第二行
[headerString appendFormat:@"Content-Disposition: form-data; name=%@; filename=%@\r\n",serverFieldName,fileSaveName];
//2.3 拼接第三行
[headerString appendString:@"Content-Type: application/octet-stream\r\n\r\n"];
//2.4 将头部的字符串转成二进制
NSData *headerData = [headerString dataUsingEncoding:NSUTF8StringEncoding];
//2.5 拼接到dataM后面
[dataM appendData:headerData];
//3.拼接内容
[dataM appendData:fileData];
[dataM appendData:[@"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
//4.拼接尾巴
NSString *tailString = [NSString stringWithFormat:@"--%@--\r\n\r\n",kBoundaryUpload];
[dataM appendData:[tailString dataUsingEncoding:NSUTF8StringEncoding]];
return dataM.copy;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
3. 下载请求
- (NSURLSession *)downLoadSession{
if (_downLoadSession==nil) {
//开发中,就用这个
NSURLSessionConfiguration *defaultConfigration = [NSURLSessionConfiguration defaultSessionConfiguration];
/**
参数1:配置
参数2:代理
参数3:队列,如果我们写的是主队列,那么代理方法在主线程调用
如果是通过 [[NSOperationQueue] alloc] init]那么代理方法在子线程调用
nil 这相当于 [[NSOperationQueue] alloc] init]
*/
_downLoadSession = [NSURLSession sessionWithConfiguration:defaultConfigration delegate:self delegateQueue:nil];
}
return _downLoadSession;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
//1.NSURL
NSURL *url = [NSURL URLWithString:@"http://localhost/videos.zip"];
//2.下载我们为了设置代理,获取进度,自己创建session
NSURLSession *downLoadSession = self.downLoadSession;
//3.由downLoadSession发起下载任务
NSURLSessionDownloadTask *downLoadTask = [downLoadSession downloadTaskWithURL:url];
//4.resume
[downLoadTask resume];
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
三、AFNetworking3.0封装思路简析
1. AFN的内部中的RunLoop
AFN内部开了一条专门用来访问网络请求的线程,在这个开线程的方法中,他把方法和dispatch_once都用static修饰了下,以保证这个方法的安全性以及只开辟一块内存空间,而且保证他线程不死,在这个方法中他会调用另一个网络请求入口的方法
在这个入口方法中他会创建一个RunLoop,然后添加一个NSMachPort端口,目的是为了让他里面有Source(因为有了Source的RunLoop才能真正跑起来)
然后启动RunLoop,通过RunLoop在里面不断的循环,不断的发送消息,让他做事情.
2. 基于NSURLSession的封装
AFHTTPSessionManager封装了HTTP请求的常见处理,包括GET/POST方法,同时还包括了解析服务器响应数据的方法
AFHTTPSessionManager的GET请求
- (NSURLSessionDataTask *)GET:(NSString *)URLString
parameters:(id)parameters
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
AFHTTPSessionManager的POST请求
- (NSURLSessionDataTask *)POST:(NSString *)URLString
parameters:(id)parameters
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
AFN解析相关
AFN在解析时候,默认解析的是JSON数据。如果想解析XML数据,就需要手动把responseSerializer 的值该掉
AFHTTPSessionManager *mgr = [AFHTTPSessionManager manager];
mgr.responseSerializer = [AFXMLParserResponseSerializer serializer];
- 1
- 2
- 1
- 2
将方法的返回值类型也改成XML,然后自己解析。
如果服务器返回的是普通的数据类型,这时就要告诉AFN用普通的数据类型来解析,服务器返回什么样,解析成什么样即可
AFHTTPSessionManager *mgr = [AFHTTPSessionManager manager];
mgr.responseSerializer = [AFHTTPResponseSerializer serializer];
AFNetworking封装思路简析的更多相关文章
- AFNetworking源码简析
AFNetworking基本是苹果开发中网络请求库的标配,它是一个轻量级的网络库,专门针对iOS和OS X的网络应用设计,具有模块化的架构和丰富的APIs接口,功能强大并且使用简单,深受苹果应用开发人 ...
- 「赛后补题」HBCPC2018题目代码与思路简析
这次比赛(2018年第二届河北省大学生程序设计竞赛)虽然没有打,但是题目还是要写的.未完成的题目(还差比较硬核的四题)和思路分析会陆续更新完. Problem A 2011 Mex Query /* ...
- [转载] Thrift原理简析(JAVA)
转载自http://shift-alt-ctrl.iteye.com/blog/1987416 Apache Thrift是一个跨语言的服务框架,本质上为RPC,同时具有序列化.发序列化机制:当我们开 ...
- 简析TCP的三次握手与四次分手【转】
转自 简析TCP的三次握手与四次分手 | 果冻想http://www.jellythink.com/archives/705 TCP是什么? 具体的关于TCP是什么,我不打算详细的说了:当你看到这篇文 ...
- Linux 目录结构学习与简析 Part2
linux目录结构学习与简析 by:授客 QQ:1033553122 ---------------接Part 1-------------- #1.查看CPU信息 #cat /proc/cpuinf ...
- [转帖]简析数据中心三大Overlay技术
简析数据中心三大Overlay技术 http://www.jifang360.com/news/20161010/n225987768.html 搭建大规模的云计算环境需要数据中心突破多种技术难题,其 ...
- Unity5中新的Shader体系简析
一.Unity5中新的Shader体系简析 Unity5和之前的书写模式有了一定的改变.Unity5时代的Shader Reference官方文档也进一步地变得丰满. 主要需要了解到的是,在原来的Un ...
- DiskGenius注册算法简析
初次接触DiskGenius已经成为遥远的记忆,那个时候还只有DOS版本.后来到Windows版,用它来处理过几个找回丢失分区的案例,方便实用.到现在它的功能越来越强大,成为喜好启动技术和桌面支持人员 ...
- SpringMVC学习(一)——概念、流程图、源码简析
学习资料:开涛的<跟我学SpringMVC.pdf> 众所周知,springMVC是比较常用的web框架,通常整合spring使用.这里抛开spring,单纯的对springMVC做一下总 ...
随机推荐
- 动态链接库dll,导入库lib,静态链接库lib
目前以lib后缀的库有两种,一种为静态链接库(Static Libary,以下简称“静态库”),另一种为动态连接库(DLL,以下简称“动态库”)的导入库(Import Libary,以下简称“导入库” ...
- 理解交互设计之"行为设计与对象设计"
本文是辛向阳教授在<装饰>杂志(大家可以关注这个权威杂志的公众号,分享给大家)2015年第1期公开发表的学术论文,文章探讨的是交互设计研究 思路的转变.这一转变不仅适用于交互设计,也适用于 ...
- C++调用C#之C# COM控件
C#做界面真的是比C++方便多了,所以尝试了一下,使用C++做核心功能(例如绘图),然后用C#来做节目(例如对话框),考虑到以后可能不能使用.net,使用DLL做一个隔离层,隔离C++和C#,方便以后 ...
- git 强制覆盖本地文件
git fetch --all git reset --hard origin/master git pull
- php实现echo json_encode正确显示汉字
<?php header('Content-type: text/html; charset=utf-8'); /* function showmessage($msg = '', $redir ...
- 给Notepad++ 加带图标右键菜单
给Notepad++ 加带图标右键菜单 方式一: 拷贝以下代码建立一个reg文件,替换相关路径,保存,双击运行加入注册表 Windows Registry Editor Version 5.00 [H ...
- Python中元素定位探讨
以下以阿里云(10.10.1.11)系统中考试答题为例进行了python脚本的编写研究.模糊定位(定位一些动态值): ————————————————————————————————————————— ...
- 笔记整理--Linux编程
linux c编程open() read() write()函数的使用方法及实例 | 奶牛博客 - Google Chrome (2013/8/31 17:56:10) 今天把文件IO操作的一些东东整 ...
- HBase的Shell命令
1.HBase提供了一个shell的终端给用户交互 2.HBase Shell的DDL操作 (1)先进入HBase的 Shell命令行,即HBASE_HOME/bin/hbase shell …… & ...
- Python之路【第二篇】:Python基础(二)
windows的换行符:\n\r linux的换行符:\n 文件的数据处理: r 以只读模式打开文件(默认模式)w 以只写模式打开文件a 以追加模式打开文件 r+b 以读写模式打开文件(以读/写方式打 ...