全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

IOS网络请求之AFNetWorking 3.x 使用详情

前言:

计划把公司的网络请求与业务解耦,所以想着学习一下网络请求,最近学习了NSURLSession,今天来学习一下基于NSURLSession封装的优秀开源框架AFNetWorking 3.x,之前13年做iOS开发时用的ASIHttpRequest开源框架。

AFNetWorking

AFNetWorking一款轻量级网络请求开源框架,基于iOS和mac os 网络进行扩展的高性能框架,大大降低了iOS开发工程师处理网络请求的难度,让iOS开发变成一件愉快的事情。

下载地址:AFNetworking_jb51.rar

1.)AFHTTPSessionManager请求管理者

-(AFHTTPSessionManager *)sharedManager
{
  AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
  //最大请求并发任务数
  manager.operationQueue.maxConcurrentOperationCount = 5;

  // 请求格式
  // 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":@"123"};
  //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":@"123"};
  //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":@"123"};
  [[self shareAFNManager] POST:url parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
    NSDate* dat = [NSDate dateWithTimeIntervalSinceNow:0];
    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:0];
    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(300, 300));
    }];
  }];
  //启动下载任务
  [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 = 5;
    manager.requestSerializer.timeoutInterval=30.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:@"XueLeTSHTTPS" 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使用  # ios网络  # afnetworking  # afnetworking网络请求  # iOS利用AFNetworking3.0——实现文件断点下载  # 详解iOS开发 - 用AFNetworking实现https单向验证  # 双向验证  # iOS AFNetworking中cookie重定向代码  # iOS应用开发中AFNetworking库的常用HTTP操作方法小结  # 下载地址  # 都是  # 开源  # 的是  # 数据格式  # 上传  # 是一种  # 放在  # 自定义  # 还需要  # 日起  # 在里面  # 要对  # 有两种  # 每次都  # 可以根据  # 高性能  # 转换成  # 提供给  # 第二种 


相关文章: 如何做网站制作流程,*游戏网站怎么搭建?  如何基于云服务器快速搭建网站及云盘系统?  如何选择服务器才能高效搭建专属网站?  如何在建站之星网店版论坛获取技术支持?  建站主机选哪家性价比最高?  保定网站制作方案定制,保定招聘的渠道有哪些?找工作的人一般都去哪里看招聘信息?  网站制作公司排行榜,抖音怎样做个人官方网站  番禺网站制作公司哪家值得合作,番禺图书馆新馆开放了吗?  建站主机空间推荐 高性价比配置与快速部署方案解析  如何通过.red域名打造高辨识度品牌网站?  存储型VPS适合搭建中小型网站吗?  网站设计制作书签怎么做,怎样将网页添加到书签/主页书签/桌面?  如何在IIS管理器中快速创建并配置网站?  如何选择高效便捷的WAP商城建站系统?  建站之星logo尺寸如何设置最合适?  手机网站制作平台,手机靓号代理商怎么制作属于自己的手机靓号网站?  定制建站方案优化指南:企业官网开发与建站费用解析  韩国服务器如何优化跨境访问实现高效连接?  建站主机选购指南:核心配置与性价比推荐解析  免费的流程图制作网站有哪些,2025年教师初级职称申报网上流程?  制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?  专业网站建设制作报价,网页设计制作要考什么证?  唐山网站制作公司有哪些,唐山找工作哪个网站最靠谱?  建站之星与建站宝盒如何选择最佳方案?  如何选择高效响应式自助建站源码系统?  建站主机是否等同于虚拟主机?  制作网站的模板软件,网站怎么建设?  建站之星如何实现PC+手机+微信网站五合一建站?  创业网站制作流程,创业网站可靠吗?  齐河建站公司:营销型网站建设与SEO优化双核驱动策略  C++用Dijkstra(迪杰斯特拉)算法求最短路径  制作网站怎么制作,*游戏网站怎么搭建?  公司网站建设制作费用,想建设一个属于自己的企业网站,该如何去做?  c# 在高并发下使用反射发射(Reflection.Emit)的性能  如何选择香港主机高效搭建外贸独立站?  如何高效生成建站之星成品网站源码?  微信h5制作网站有哪些,免费微信H5页面制作工具?  专业网站制作服务公司,有哪些网站可以免费发布招聘信息?  免费ppt制作网站,有没有值得推荐的免费PPT网站?  做企业网站制作流程,企业网站制作基本流程有哪些?  临沂网站制作公司有哪些,临沂第四中学官网?  官网建站费用明细查询_企业建站套餐价格及收费标准指南  ,购物网站怎么盈利呢?  高防服务器如何保障网站安全无虞?  已有域名如何免费搭建网站?  建站之星备案流程有哪些注意事项?  完全自定义免费建站平台:主题模板在线生成一站式服务  GML (Geography Markup Language)是什么,它如何用XML来表示地理空间信息?  大连 网站制作,大连天途有线官网?  建站之星CMS五站合一模板配置与SEO优化指南 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。