IOS网络请求之AFNetWorking 3.x 使用
前言:
计划把公司的网络请求与业务解耦,所以想着学习一下网络请求,最近学习了NSURLSession,今天来学习一下基于NSURLSession封装的优秀开源框架AFNetWorking 3.x,之前13年做iOS开发时用的ASIHttpRequest开源框架。
AFNetWorking
AFNetWorking一款轻量级网络请求开源框架,基于iOS和mac os 网络进行扩展的高性能框架,大大降低了iOS开发工程师处理网络请求的难度,让iOS开发变成一件愉快的事情。
GitHub地址:https://github.com/AFNetworking/AFNetworking
1.)AFHTTPSessionManager请求管理者
-(AFHTTPSessionManager *)sharedManager
{
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//最大请求并发任务数
manager.operationQueue.maxConcurrentOperationCount = ; // 请求格式
// AFHTTPRequestSerializer 二进制格式
// AFJSONRequestSerializer JSON
// AFPropertyListRequestSerializer PList(是一种特殊的XML,解析起来相对容易) manager.requestSerializer = [AFHTTPRequestSerializer serializer]; // 上传普通格式 // 超时时间
manager.requestSerializer.timeoutInterval = 30.0f;
// 设置请求头
[manager.requestSerializer setValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"];
// 设置接收的Content-Type
manager.responseSerializer.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"application/xml", @"text/xml",@"text/html", @"application/json",@"text/plain",nil]; // 返回格式
// AFHTTPResponseSerializer 二进制格式
// AFJSONResponseSerializer JSON
// AFXMLParserResponseSerializer XML,只能返回XMLParser,还需要自己通过代理方法解析
// AFXMLDocumentResponseSerializer (Mac OS X)
// AFPropertyListResponseSerializer PList
// AFImageResponseSerializer Image
// AFCompoundResponseSerializer 组合 manager.responseSerializer = [AFJSONResponseSerializer serializer];//返回格式 JSON
//设置返回C的ontent-type
manager.responseSerializer.acceptableContentTypes=[[NSSet alloc] initWithObjects:@"application/xml", @"text/xml",@"text/html", @"application/json",@"text/plain",nil]; return manager;
}
2.)处理get请求
-(void)doGetRequest
{
//创建请求地址
NSString *url=@"http://api.nohttp.net/method";
//构造参数
NSDictionary *parameters=@{@"name":@"yanzhenjie",@"pwd":@""};
//AFN管理者调用get请求方法
[[self shareAFNManager] GET:url parameters:parameters progress:^(NSProgress * _Nonnull downloadProgress) {
//返回请求返回进度
NSLog(@"downloadProgress-->%@",downloadProgress);
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
//请求成功返回数据 根据responseSerializer 返回不同的数据格式
NSLog(@"responseObject-->%@",responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//请求失败
NSLog(@"error-->%@",error);
}];
}
3.)处理post请求
-(void)doPostRequestOfAFN
{
//创建请求地址
NSString *url=@"http://api.nohttp.net/postBody";
//构造参数
NSDictionary *parameters=@{@"name":@"yanzhenjie",@"pwd":@""};
//AFN管理者调用get请求方法
[[self shareAFNManager] POST:url parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
//返回请求返回进度
NSLog(@"downloadProgress-->%@",uploadProgress);
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
//请求成功返回数据 根据responseSerializer 返回不同的数据格式
NSLog(@"responseObject-->%@",responseObject);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//请求失败
NSLog(@"error-->%@",error);
}];
}
4.)处理文件上传
-(void)doUploadRequest
{
// 创建URL资源地址
NSString *url = @"http://api.nohttp.net/upload";
// 参数
NSDictionary *parameters=@{@"name":@"yanzhenjie",@"pwd":@""};
[[self shareAFNManager] POST:url parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
NSDate* dat = [NSDate dateWithTimeIntervalSinceNow:];
NSTimeInterval a=[dat timeIntervalSince1970];
NSString* fileName = [NSString stringWithFormat:@"file_%0.f.txt", a]; [FileUtils writeDataToFile:fileName data:[@"upload_file_to_server" dataUsingEncoding:NSUTF8StringEncoding]];
// 获取数据转换成data
NSString *filePath =[FileUtils getFilePath:fileName];
// 拼接数据到请求题中
[formData appendPartWithFileURL:[NSURL fileURLWithPath:filePath] name:@"headUrl" fileName:fileName mimeType:@"application/octet-stream" error:nil]; } progress:^(NSProgress * _Nonnull uploadProgress) {
// 上传进度
NSLog(@"%lf",1.0 *uploadProgress.completedUnitCount / uploadProgress.totalUnitCount);
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
//请求成功
NSLog(@"请求成功:%@",responseObject); } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//请求失败
NSLog(@"请求失败:%@",error);
}];
}
5.)处理文件下载
-(void)doDownLoadRequest
{
NSString *urlStr =@"http://images2015.cnblogs.com/blog/950883/201701/950883-20170105104233581-62069155.png";
// 设置请求的URL地址
NSURL *url = [NSURL URLWithString:urlStr];
// 创建请求对象
NSURLRequest *request = [NSURLRequest requestWithURL:url];
// 下载任务
NSURLSessionDownloadTask *task = [[self shareAFNManager] downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
// 下载进度
NSLog(@"当前下载进度为:%lf", 1.0 * downloadProgress.completedUnitCount / downloadProgress.totalUnitCount);
} destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
// 下载地址
NSLog(@"默认下载地址%@",targetPath);
//这里模拟一个路径 真实场景可以根据url计算出一个md5值 作为fileKey
NSDate* dat = [NSDate dateWithTimeIntervalSinceNow:];
NSTimeInterval a=[dat timeIntervalSince1970];
NSString* fileKey = [NSString stringWithFormat:@"/file_%0.f.txt", a];
// 设置下载路径,通过沙盒获取缓存地址,最后返回NSURL对象
NSString *filePath = [FileUtils getFilePath:fileKey];
return [NSURL fileURLWithPath:filePath]; // 返回的是文件存放在本地沙盒的地址
} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
// 下载完成调用的方法
NSLog(@"filePath---%@", filePath);
NSData *data=[NSData dataWithContentsOfURL:filePath];
UIImage *image=[UIImage imageWithData:data];
// 刷新界面...
UIImageView *imageView =[[UIImageView alloc]init];
imageView.image=image;
[self.view addSubview:imageView];
[imageView mas_makeConstraints:^(MASConstraintMaker *make) {
make.center.equalTo(self.view);
make.size.mas_equalTo(CGSizeMake(, ));
}];
}];
//启动下载任务
[task resume];
}
6.)网络状态监听
- (void)aFNetworkStatus{
//创建网络监测者
AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
/*枚举里面四个状态 分别对应 未知 无网络 数据 WiFi
typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
AFNetworkReachabilityStatusUnknown = -1, 未知
AFNetworkReachabilityStatusNotReachable = 0, 无网络
AFNetworkReachabilityStatusReachableViaWWAN = 1, 蜂窝数据网络
AFNetworkReachabilityStatusReachableViaWiFi = 2, WiFi
};
*/
[manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
//这里是监测到网络改变的block 可以写成switch方便
//在里面可以随便写事件
switch (status) {
case AFNetworkReachabilityStatusUnknown:
NSLog(@"未知网络状态");
break;
case AFNetworkReachabilityStatusNotReachable:
NSLog(@"无网络");
break;
case AFNetworkReachabilityStatusReachableViaWWAN:
NSLog(@"蜂窝数据网");
break;
case AFNetworkReachabilityStatusReachableViaWiFi:
NSLog(@"WiFi网络");
break;
default:
break;
}
}] ;
[manager startMonitoring];
}
AFNetWorking内存泄露
通常情况我们一般会认为以manager结尾的都是单例模式,所以我们一般都是这样使用AFNetWorking,如下
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
其实我们点进去查看源码发现并不是单例,而是每次都实例化一个AFHTTPSessionManager对象,源码如下
+ (instancetype)manager {
return [[[self class] alloc] initWithBaseURL:nil];
}
所以我们在使用AFNetWorking的时候要对AFHTTPSessionManager进行单例封装
+ (AFHTTPSessionManager *)sharedManager
{
static AFHTTPSessionManager *manager = nil;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
manager = [AFHTTPSessionManager manager];
manager.operationQueue.maxConcurrentOperationCount = ;
manager.requestSerializer.timeoutInterval=.f;
manager.responseSerializer.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"application/xml", @"text/xml",@"text/html", @"application/json",@"text/plain",nil];
[manager.requestSerializer setValue:@"gzip" forHTTPHeaderField:@"Content-Encoding"]; });
return manager;
}
AFNetWorking关于HTTPS
在2017年1月1日起Apple 要求开发者于年底之前为提交至 App Store 中的应用启用 HTTPS ,以支持 iOS 9 引入的 ATS(App Transport Security)技术。但后来,apple 发布声明宣布延长这个时限,提供给开发者更多的时间进行相关准备。目前 Apple 尚未公布新的截止日期。所以目前应对https的方案有两种。
第一种方式:
屏蔽调iOS ATS(App Transport Security),在pList.info文件中添加如下代码
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
第二种方式:
配置https CA证书,这里采用获取NSBundle中获取CA证书,AFNetWorking提供了配置AFSecurityPolicy模块
+ (AFSecurityPolicy *)customSecurityPolicy{
//Https CA证书地址
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"HTTPSCer" ofType:@"cer"];
//获取CA证书数据
NSData *cerData = [NSData dataWithContentsOfFile:cerPath];
//创建AFSecurityPolicy对象
AFSecurityPolicy *security = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
//设置是否允许不信任的证书(证书无效、证书时间过期)通过验证 ,默认为NO.
security.allowInvalidCertificates = YES;
//是否验证域名证书的CN(common name)字段。默认值为YES。
security.validatesDomainName = NO;
//根据验证模式来返回用于验证服务器的证书
security.pinnedCertificates = [NSSet setWithObject:cerData];
return security;
}
然后通过设置AFHTTPSessionManager的securityPolicy属性等于自定义的AFSecurityPolicy。
总结:
简单记录一下AFNetWorking的基本使用,方便以后查找。
IOS网络请求之AFNetWorking 3.x 使用的更多相关文章
- IOS网络请求框架AFNetworking和ASIHttpRequest对比
ASI基于CFNetwork框架开发,而AFN基于NSURL. ASI更底层,请求使用创建CFHTTPMessageRef进行,使用NSOperationQueue进行管理,ASIHTTPReques ...
- 【转载】一步一步搭建自己的iOS网络请求库
一步一步搭建自己的iOS网络请求库(一) 大家好,我是LastDay,很久没有写博客了,这周会分享一个的HTTP请求库的编写经验. 简单的介绍 介绍一下,NSURLSession是iOS7中新的网络接 ...
- 对比iOS网络组件:AFNetworking VS ASIHTTPRequest
对比iOS网络组件:AFNetworking VS ASIHTTPRequest 作者 高嘉峻 发布于 2013年2月28日 | 7 讨论 分享到:微博微信FacebookTwitter有道云笔记邮件 ...
- springmvc接口ios网络请求
springmvc: application/json;charset=utf-8的ios网络请求: 后台使用 @RequestBody注解参数接收:
- iOS网络请求-AFNetworking源码解析
趁着端午节日,自己没有什么过多的安排,准备花4-5天左右,针对网络请求源码AFNetworking和YTKNetwork进行解析以及这两年多iOS实际开发经验(其实YTKNetwork也是对AFNet ...
- iOS开发之网络请求(基于AFNetworking的再封装)
最近一直很忙也没有什么时间写博客了.放假了休息一下,就写一篇博客来总结一下最近做项目中出现过的问题吧!!! 首先,在项目中我的起到了什么作用,无非就是把美工(UI设计师)给我们的图显示出来,然后再和服 ...
- 网络请求工具--AFNetworking 分类: ios技术 2015-02-03 08:17 76人阅读 评论(0) 收藏
在我们开发过程中,网络请求是必不可少的,对于网络框架,现在主流的大概只有三类:ASI框架: HTTP终结者(已经停止更新了),MKNetworkKit ,AFN.今天我就来浅谈一下这个AFN AFNe ...
- 对比iOS网络组件:AFNetworking VS ASIHTTPRequest(转载)
在开发iOS应用过程中,如何高效的与服务端API进行数据交换,是一个常见问题.一般开发者都会选择一个第三方的网络组件作为服务,以提高开发效率和稳定性.这些组件把复杂的网络底层操作封装成友好的类和方法, ...
- iOS网络请求基础
这篇是关于网络请求的,结合公司的实际情况编写,如果有不同意见欢迎留言共同讨论. iOS在9.0之后彻底放弃了NSURLConnection,现在已经改用了NSURLSession进行网络请求.一般现在 ...
随机推荐
- thinkphp中的ajax分页
thinkphp中用ajax分页和普通的ajax分页的区别在于处理位置的不同,thinkphp是在控制器的方法中处理ajax传的值,然后返回数据.下面是一个点击事件触发后,显示的内容用ajax分页. ...
- (简单) POJ 2406 Power Strings,扩展KMP。
Description Given two strings a and b we define a*b to be their concatenation. For example, if a = & ...
- (简单) LightOJ 1074 Extended Traffic,SPFA+负环。
Description Dhaka city is getting crowded and noisy day by day. Certain roads always remain blocked ...
- (中等) HDU 4370 0 or 1,建模+Dijkstra。
Description Given a n*n matrix C ij (1<=i,j<=n),We want to find a n*n matrix X ij (1<=i,j&l ...
- [iOS]C语言知识点系列视频
C语言知识点系列视频 目录 C语言技术视频-01-变量的定义 C语言技术视频-02-程序分支结构(if...else) C语言技术视频-03-程序分支结构(switch) C语言技术视频-04-程序循 ...
- HTML学习(八)列表和块
无序列表无序列表是一个项目的列表,此列项目使用粗体圆点(典型的小黑圆圈)进行标记.无序列表始于 <ul> 标签.每个列表项始于 <li>.<ul type=“”> ...
- css颜色渐变在不同浏览器的设置
在web开发中,难免会遇到浏览器之间的兼容问题,关于Css设置颜色渐变下面有解决的办法,直接上代码: 适用于谷歌浏览器: background: -webkit-gradient(linear, 0 ...
- Chapter5 – 碰撞检测
主人公能够放子弹了,虽然子弹看起来很美,但是怎么样来打到妖怪? 在这一章我们介绍一下最简单的碰撞检测方法去实现它. 首先第一个,我们有必要保存每个妖怪和子弹的指针,来够追踪他们的位置. 在这个游戏中我 ...
- zend framework 1.10项目配置与经典hello world
准备工作 前置条件:PHP>=5.14,Apache开启mod_rewrite支持,开启php的pdo扩展. Zend Framework 要求 PHP版本不低于5.1.4,但强烈建议使用 5. ...
- ECSHOP session
ECSHOP session传值 <?phpclass cls_session{ var $session_table = ''; ; // SESSION 过期时间 var $sess ...