从架构设计的角度分析ios自带网络库和AFNetworking

总结(先说明文章分析出的一些‘认知’)

从本文中,我们可以总结出一些框架设计上的“认知”:

  • 对于通用的常规配置信息方面的设计,我们可以通过定义一个“类似于NSURLSessionConfiguration、NSURLRequest”的类来完成设计;
  • 对于生命周期的时机的通知,我们可以通过抽象出一个“类似于NSURLSessionDataDelegate”的协议来完成设计,此时对于框架的使用方来说,就可以根据这些“生命周期的时机的通知”来实现自己的各种各样的业务逻辑。(提升可扩展性)
  • 对于一些通用且常用的处理逻辑代码,我们直接以工具类的方式来完成设计。(降低重复开发的成本)

ios系统自带的网络库

因为AFNetworking是对ios系统自带的网络库的接口(比如NSURLSession)进行封装的,因此我们先了解系统自带的网络库,然后再了解AFNetworking。
学习网络库api的最好方法就是写个demo,所以,我们先来看一个demo。

Demo1

本demo是请求https://www.baidu.com,然后打印响应的数据。

  1. demo代码如下:
//D2VC是个UIViewController 
@interface D2VC () <NSURLSessionDataDelegate>
@property(nonatomic) NSMutableData *resultData;
@end@implementation D2VC- (void)viewDidLoad {[super viewDidLoad];self.view.backgroundColor = UIColor.whiteColor;UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 100, 390, 60)];button.backgroundColor = UIColor.redColor;[button addTarget:self action:@selector(get) forControlEvents:UIControlEventTouchUpInside];[button setTitle:@"get请求" forState:UIControlStateNormal];[self.view addSubview:button];
}- (void)get {//创建网络请求NSURL *url = [NSURL URLWithString:@"https://www.baidu.com"];NSURLRequest *reuqest = [NSURLRequest requestWithURL:url];//初始化请求响应的回调方法所在的队列NSOperationQueue *operationQueue = [[NSOperationQueue alloc] init];operationQueue.maxConcurrentOperationCount = 1;//初始化NSURLSession。第3个参数必须是个串行队列NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:operationQueue];//初始化一个请求任务NSURLSessionDataTask *task = [session dataTaskWithRequest:reuqest];//开始请求[task resume];
}#pragma mark - NSURLSessionDataDelegate- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTaskdidReceiveResponse:(NSURLResponse *)responsecompletionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {NSLog(@"%s, thread=%@。该方法是在你创建session时所传入的operationQueue中被调用的,所以如果你传的是mainQueue,那么该方法就会在UI线程执行。该方法被调用时,app就已经发生并收到响应了。。。如果你在该方法不调用completionHandler,那么下面的那两个方法就不会被执行!", __func__, [NSThread currentThread]);completionHandler(NSURLSessionResponseAllow); //调用该方法的目的是接收服务端的响应,此时下面的两个方法会被调用以便接收服务端的响应数据self.resultData = [NSMutableData data];
}/* 接收到server响应的数据时被调用,如果数据很多,就会被调用多次*/
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTaskdidReceiveData:(NSData *)data {NSLog(@"%s, thread=%@.接收到服务端响应的data。该方法是在你创建session时所传入的operationQueue中被调用的,所以如果你传的是mainQueue,那么该方法就会在UI线程执行。接下来保存该data到resultData中", __func__, [NSThread currentThread]);[self.resultData appendData:data];
}/* 请求完成时被回调,error表示成功或者失败*/
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didCompleteWithError:(nullable NSError *)error {NSLog(@"%s, thread=%@", __func__, [NSThread currentThread]);if (!error) {NSLog(@"请求完成了,且请求成功.该方法是在你创建session时所传入的operationQueue中被调用的,所以如果你传的是mainQueue,那么该方法就会在UI线程执行。");NSLog(@"服务端响应的数据是:%@", [[NSString alloc] initWithData:self.resultData encoding:NSUTF8StringEncoding]);} else {NSLog(@"请求完成了,但请求失败了.该方法是在你创建session时所传入的operationQueue中被调用的,所以如果你传的是mainQueue,那么该方法就会在UI线程执行。,error=%@", error);}
}@end
  1. 运行demo,然后点击请求按钮
    在这里插入图片描述
  2. 请求结果如下图。
    在这里插入图片描述

网络库的类关系图

根据上面demo用到的系统自带的网络相关的类及其关联的类,我们便可以梳理出目前ios的网络相关的类的关系如下图所示:
在这里插入图片描述
我们再结合本demo所使用的网络相关的类和协议来看看这些类或者协议所提供的功能。如下图,我们通过实现NSURLSessionDataDelegate协议来接收服务端返回的数据,并将其打印出来,使用NSURLSessionDataTask来发起“请求”,使用NSURLSession来获取请求任务(NSURLSessionDataTask),使用NSURLSessionConfiguration配置session的一些策略(比如请求超时时间),使用NSOperationQueue来让执行“NSURLSessionDataDelegate协议的实现方法”,使用NSURLRequest来配置请求策略(比如请求url)。
在这里插入图片描述
从本demo中,我们可以总结出,在框架的设计里面:对于通用的常规配置信息方面的设计,我们可以通过定义一个“类似于NSURLSessionConfiguration、NSURLRequest”的类来完成设计;对于生命周期的时机的通知,我们可以通过抽象出一个“类似于NSURLSessionDataDelegate”的协议来完成设计,此时对于框架的使用方来说,就可以根据这些“生命周期的时机的通知”来实现自己的各种各样的业务逻辑

AFNetworking

Demo2

本demo是请求https://www.baidu.com,然后打印响应的数据。

  1. demo代码如下:
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"text/html",@"application/json", @"text/json" ,@"text/javascript", nil];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
[manager GET:@"https://www.baidu.com" parameters:nil headers:nil progress:^(NSProgress * _Nonnull downloadProgress) {NSLog(@"csx,fractionCompleted=%lf", downloadProgress.fractionCompleted);} success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {NSLog(@"csx,response=%@", responseObject);} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {NSLog(@"csx,error=%@", error);
}];
  1. 运行代码,得到的请求结果如下图。
    在这里插入图片描述

AFNetworking和系统网络库的类关系图

建议先看看https://www.jianshu.com/p/486b1b19cc6d文章里面的请求处理流程,然后再往下看。
根据上面demo用到的网络相关的类及其关联的类,我们便可以梳理出如下类图:
在这里插入图片描述
我们再结合本demo所使用的类来看看这些类所提供的功能。如下图,我们使用AFHTTPSessionManager的GET方法来发起“请求”,使用AFHTTPResponseSerializer来解析服务端返回的数据。
在这里插入图片描述
从本demo中,我们可以总结出:

  • AFNetworking框架提供了多个将请求参数序列化的功能类,比如AFHTTPRequestSerializer类,该类针对GET请求方式的请求, 会把请求参数以键值对的方式拼接到请求url中。框架的使用方可以根据需要来选择合适的序列化功能类,如果这些功能类都不满足,那么使用方可以通过实现AFURLRequestSerialization协议来自定义自己的序列化方式
  • AFNetworking框架提供了多个将响应数据按某种格式解析的功能类,比如AFHTTPResponseSerializer类,该类会按照http协议的标准解析出响应数据中的响应头、响应体的数据。框架的使用方可以根据需要来选择合适的序列化功能类,如果这些功能类都不满足,那么使用方可以通过实现AFURLResponseSerialization协议来自定义自己的序列化方式
  • AFNetworking框架基于NSURLSession封装了‘使用NSURLSession发起请求和响应请求时的常用操作步骤’。比如,如果我们使用NSURLSession来请求某个网址,那么我们会先初始化NSURLSession,然后用该NSURLSession来获取一个NSURLSessionDataTask实例对象,接着调用NSURLSessionDataTask实例对象的resume方法,然后通过NSURLSession的delegate来获取响应数据,然后解析响应数据,最后再处理解析后的数据(具体代码请看前面的Demo1)。而如果我们使用AFNetworking来请求某个网址的话,那么我们只需要调用初始化AFHTTPSessionManager,然后调用该类的
    GET:parameters:headers:progress:success:failure:方法即可获取到解析后的响应数据,然后就可以根据业务需要来处理解析后的数据了

我们再来看看AFURLSessionManager类的.h文件,如下图,发现该类暴露了很多系统自带的网络相关的类,比如NSURLSession、NSURLSessionDataTask、NSURLSessionConfiguration,也就是说,对于配置请求超时时间等ios系统自带的网络配置等,AFNetworking会直接暴露出来让框架的使用方来配置,而不是将这些配置封装起来
在这里插入图片描述
所以,AFNetworking库带来的好处是降低了网络请求的开发成本,具体体现在:

  • AFNetworking把NSURLSession的常规使用步骤封装成GET、POST等多个方法,框架使用方只需要调用某个方法即可完成请求的发起和响应数据的解析;
  • AFNetworking内部实现了很多通用且常用的序列化工具类,比如AFHTTPResponseSerializer、AFHTTPRequestSerializer、AFJSONResponseSerializer,框架使用方可以直接使用这些序列化工具类来完成数据的解析。如果这些工具类都不满足框架使用方的诉求,那么框架使用方可以通过实现AFURLRequestSerialization或者AFURLResponseSerialization协议来自定义自己的解析逻辑。

所以,对于一些通用且常用的处理逻辑代码,我们直接以工具类的方式来设计

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/36124.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【算法专题--栈】后缀表达式求值 -- 高频面试题(图文详解,小白一看就会!!)

目录 一、前言 二、题目描述 三、解题方法 ⭐解题思路 ⭐案例图解 四、总结与提炼 五、共勉 一、前言 后缀表达式求值 这道题&#xff0c;可以说是--栈专题--&#xff0c;最经典的一道题&#xff0c;也是在面试中频率最高的一道题目&#xff0c;通常在面试中&…

什么是ArchiMate?有优缺点和运用场景?

一、什么是ArchiMate? ArchiMate是一种由The Open Group发布的企业级标准&#xff0c;它是一种整合多种架构的可视化业务分析模型语言&#xff0c;也属于架构描述语言&#xff08;ADL&#xff09;。ArchiMate主要从业务、应用和技术三个层次&#xff08;Layer&#xff09;&…

QT在visual studio环境打开控制台窗口

明确需求 在VS环境中开发QT应用&#xff0c;有时遇到BUG想看日志&#xff0c;但是默认VS环境没有显示控制台窗口可看日志。 解决方法 对工程名单击右键。 点击属性&#xff0c;在打开界面按照如下图操作。 设置完成后弹出的控制台窗口如下图。

[Cloud Networking] VLAN

1 为什么需要 VLAN(Virtual Local Area Network) VLAN是一个逻辑网络&#xff0c;VLAN将设备/用户进行逻辑分组&#xff0c;VLAN需要在Switch上创建。为什么需要这样呢&#xff1f;为何不能所有设备都在同一个网络&#xff1f; 如下网络&#xff0c;如果设备过多&#xff0c;…

【日记】怎么上了一天班饭都没得吃(659 字)

正文 今天算是混得最惨的一天了。 下午开始&#xff0c;柜面主管出差&#xff0c;她找了个代班&#xff0c;好家伙&#xff0c;代班直接不下来&#xff0c;于是整个营业室就只有我一个人了。所有客户逮着我一个人薅。我才下来一个月啊…… 明天她还不回来&#xff0c;要下周一&…

【UE5.3】笔记6-第一个简单小游戏

打砖块小游戏&#xff1a; 1、制造一面砖块组成的墙 在关卡中放置一个cube&#xff0c;放这地面上&#xff0c;将其转换成蓝图类,改名BP_Cube&#xff0c;更换砖块的贴图&#xff0c;按住alt键进行拷贝&#xff0c;堆出一面墙&#xff0c;复制出来的会很多&#xff0c;全选移动…

报餐小程序可以运用在饭堂的哪方面

随着科技的快速发展&#xff0c;智能化、信息化的管理方式逐渐渗透到我们日常生活的方方面面。在饭堂管理中&#xff0c;报餐小程序的应用为传统的餐饮管理方式带来了革命性的变革。本文将探讨报餐小程序在饭堂管理中的应用及其带来的优势。 一、报餐小程序的基本功能 报餐小程…

数据资产管理的艺术:构建智能化、精细化的数据资产管理体系,从数据整合、分析到决策支持,为企业提供一站式的数据资产解决方案,助力企业把握数字时代的新机遇

一、引言 在数字化浪潮席卷全球的今天&#xff0c;数据已经成为企业最重要的资产之一。如何高效、安全地管理这些海量数据&#xff0c;从中提取有价值的信息&#xff0c;并将其转化为决策支持&#xff0c;是每个企业都必须面对的挑战。本文将探讨数据资产管理的艺术&#xff0…

新风口不再是直播,云微客带你领略短视频矩阵的魅力

只要你细心观察&#xff0c;就能发现很多品牌都在做短视频矩阵&#xff0c;正是凭借大量的短视频矩阵账号带来的流量曝光&#xff0c;这些品牌才能覆盖数以万计的客户人群&#xff0c;才能每天不断地产生新订单。 有很多人觉得矩阵不就是多注册账号吗&#xff1f;其实短视频矩阵…

mysql 查找表中重复数据 类型题目

只要后续 有查找重复数据的题目 都可以 借鉴 给你 一个表 里面 只有 id 字段&#xff0c;和一个 num字段 查找 num 字段中 相同数值 出现的次数大于等于2的 数值 1. 我们 首先可以想到 分表 把这一张表分成两张表 查询 两张表的num 值相同的 且 id 不同的&#xff0c;但是…

循环冗余校验

循环冗余校验&#xff08;Cyclic Redundancy Check&#xff0c;简称CRC&#xff09;是一种广泛使用的错误检测编码技术&#xff0c;用于检测数据在传输或存储过程中是否发生错误。CRC通过在数据后面添加一个校验值&#xff08;通常称为CRC码或CRC校验和&#xff09;来实现错误检…

代理IP对SEO影响分析:提升网站排名的关键策略

你是否曾经为网站排名难以提升而苦恼&#xff1f;代理服务器或许就是你忽略的关键因素。在竞争激烈的互联网环境中&#xff0c;了解代理服务器对SEO的影响&#xff0c;有助于你采取更有效的策略&#xff0c;提高网站的搜索引擎排名。本文将为你详细分析代理服务器在SEO优化中的…

node项目-使用http模块发送get-post请求

前言 http模块是node.js提供内置模块&#xff0c;可以用来发送请求使用场景是本身这个node服务就是后端&#xff0c;调用第三方api或者其他服务使用http模块http模块和axios本质上是一个东西&#xff0c;看自己怎么选择使用 代码实现-不能直接复制-看注释 1.请求文件代码 /…

EtherCAT主站IGH-- 2 -- IGH之coe_emerg_ring.h/c文件解析

EtherCAT主站IGH-- 2 -- IGH之coe_emerg_ring.h/c文件解析 0 预览一 该文件功能coe_emerg_ring.c 文件功能函数预览 二 函数功能介绍coe_emerg_ring.c 中主要函数的作用1. ec_coe_emerg_ring_init2. ec_coe_emerg_ring_clear3. ec_coe_emerg_ring_size4. ec_coe_emerg_ring_pus…

聊聊啥项目适合做自动化测试

作为测试从业者&#xff0c;你是否遇到过这样的场景&#xff0c;某天公司大Boss找你谈话。 老板&#xff1a;小李&#xff0c;最近工作辛苦了 小李&#xff1a;常感谢您的认可&#xff0c;这不仅是对我个人的鼓励&#xff0c;更是对我们整个团队努力的认可。我们的成果离不开每…

Linux libreoffice安装 word转pdf 中文乱码(缺少字体解决)

libreoffice 的安装 yum install -y libreoffice版本验证 libreoffice --version参考文章 word转pdf 命令 转换命令 要将Word文档(.doc或.docx)转换为PDF格式&#xff0c;可以使用以下命令&#xff1a; libreoffice --headless --convert-to pdf your_word_document.docx指…

计算机视觉——OpenCV C++实现凸包

概述 在图像中发现和分析形式是解决大多数计算机视觉问题的技巧之一&#xff0c;获取轮廓是其中之一。对于新手来说&#xff0c;我会将轮廓描述为“仅仅是一条连接所有位于形状边缘上的点的曲线。” 假设我有下面这张手的图像&#xff0c;手的轮廓由绿线表示。红点代表我们将…

http服务网络请求如何确保数据安全(含python示例源码)

深度学习类文章回顾 【YOLO深度学习系列】图像分类、物体检测、实例分割、物体追踪、姿态估计、定向边框检测演示系统【含源码】 【深度学习】物体检测/实例分割/物体追踪/姿态估计/定向边框/图像分类检测演示系统【含源码】 【深度学习】YOLOV8数据标注及模型训练方法整体流程…

RabbitMQ消息积压比较厉害,然后突然丢弃

RabbitMQ中的消息积压陡降通常表明某些突发事件或操作已经显著减少了队列中的消息数量。这种现象可能由多种原因引起&#xff0c;以下是一些可能的原因及其解释&#xff1a; 消费者处理速度突然增加 原因: 你的消费者&#xff08;消费者应用或服务&#xff09;可能在某个时间点…

FreeRTOS信号量和互斥量

信息量 简介 信号量是一种解决同步问题的机制&#xff0c;可以实现对共享资源的有序访问。 前面介绍的队列(queue)可以用于传输数据&#xff1a;在任务之间、任务和中断之间。 消息队列用于传输多个数据&#xff0c;但是有时候我们只需要传递状态&#xff0c;这个状态值需要用…