前言

这个网络请求框架主要是参考了YTKNetwork的实现思路,结合自己工程进行了进一步的封装,这个框架比较适合大型业务比较复杂的app。

基本组成

具体功能

基本功能

能够正常的进行GET,POST,PUT,DELETE,HEAD,PATCT 等网络请求,能够实现文件的上传下载等功能。这个大多数网络请求都能够实现。

高级功能

1)支持链式网络请求

所谓链式网络请求就是一个请求完了,接着执行下一个网络请求。一个网络请求开始的前提必须是上一个网络请求正常结束。允许提前结束链式网络请求

2)支持类组队列的网络请求

组队列发送网络请求,一组网络请求,异步发送,可以指定某几个请求是必须成功的请求,只有指定的请求都成功时,才会执行组队列的成功回调;如果指定的任意一个请求失败,那么执行组队列的失败回调。如果没有指定必须成功的请求,那么只要有一个请求成功,那么等到所有的请求执行完,执行组队列的成功回调;如果所有的请求都失败了,那么执行组队列的失败回调。

3)支持启动时的网络请求依赖

支持启动时所有的网络请求都依赖有一个单独的网络请求,或者只链式组合请求,或者类组队列组合网络请求。等到被依赖的网络请求执行完以后才会执行其他的网络请求。多用于app有启动配置的情况。

4)支持网络请求的取消

支持网络请求的取消存在两种情况,第一种情况就是该网络请求在网络请求池中,但是还没有发送网络请求这种情况直接将该网络请求从请求池中移除掉;第二种情况就是该网络请求已经发送,但是还没有收到返回。这种情况移除该网络请求返回时对应的的回调,等到网络请求返回时,不再执行额外的逻辑,节省资源,避免出错。

5)支持mock

支持对网络请求进行mock配置,能够拦截指定的接口,并重定向到指定mock平台或者本地服务器等。实现高效的并行开发。

6)支持资源文件下载优先走cdn

如果项目中的资源文件有配置在cdn,那么可以使用优先使用cdn资源的选项

7)支持网络请求安全策略配置

可以实现网络请求安全策略的配置,可以实现全局配置,也可以实现局部的配置(针对某些特殊的网络请求)

8) 支持文件下载时断点续传,后台下载

支持下载文件时断点续传;支持文件下载时app进入后台,仍然可以下载。方便大文件的下载

扩展型功能

1)支持请求加签

能够支持不同规则的网络请求加签。甚至是同一个应用中能够支持多套网络请求加签规则。

2)支持接口缓存

能够支持对接口返回数据的缓存,设置缓存时间等,甚至在一个应用中可以支持多套缓存框架,替换某一个时能够做到平稳过渡。

3)支持域名动态更换

支持域名动态更换,肯定也支持域名的全局更换了,避免由于域名问题给app使用带来麻烦。可以支持多套域名更换及系统,能够做到平滑的过渡到某个系统。

4)全局配置网络请求指示器

能够全局的配置网络请求指示器,网络请求开始,自动出现,网络请求结束自动消失,同时对于某一个或者某一些可以配置自定义的网络请求指示器。

5)请求url配置公共参数

支持在发送网络请求前,能够对url添加公共的path,以及公共query参数。既能够实现全局配置,也可以对某些,某个请求单独配置。

6)支持数据解析过程在子线程处理

数据解析转换为模型是一个耗时操作,将这个过程放在子线程执行,可以减少主线程时间消耗, 降低出现卡顿概率

使用教程

1) 全局配置

[JKNetworkConfig sharedConfig].baseUrl = @"https://abcd.com";[[JKNetworkConfig sharedConfig] configRequestHelper:[JKRequestHelper new]];//JKRequestHelper 是JKRequestHelperProtocol协议的实现者,如果只是实现基本功能,这一行代码不需要

1)普通的网络请求

GET请求

JKBaseRequest *request = [JKBaseRequest new];
request.requestUrl = @"/a1";
[request startWithCompletionBlockWithSuccess:^(__kindof JKBaseRequest * request) {
NSLog(@"AAA %@",request.responseJSONObject);
} failure:^(__kindof JKBaseRequest * request) {}];

POST请求


JKBaseRequest *request = [JKBaseRequest new];
request.requestUrl = @"/a2";
request.requestMethod = JKRequestMethodPOST;
request.requestArgument = @{@"name":@"jack"};
[request startWithCompletionBlockWithSuccess:^(__kindof JKBaseRequest * request) {
NSLog(@"BBB %@",request.responseJSONObject);
} failure:^(__kindof JKBaseRequest * request) {}];

下载请求

JKBaseDownloadRequest *downloadRequest = [JKBaseDownloadRequest initWithUrl:@"http://g.hiphotos.baidu.com/image/pic/item/c2cec3fdfc03924590b2a9b58d94a4c27d1e2500.jpg"];
downloadRequest.backgroundPolicy = JKDownloadBackgroundRequire;// 下载文件有三种下载策略,大家感兴趣的话可以搜下JKDownloadBackgroundPolicy 这个枚举
[downloadRequest downloadWithProgress:^(NSProgress * _Nonnull downloadProgress) {
NSLog(@"progress %@",downloadProgress.localizedDescription);
} success:^(__kindof JKBaseRequest * request) {
NSLog(@"success %@",downloadRequest.downloadedFilePath);
} failure:^(__kindof JKBaseRequest * request) {
NSLog(@"failure");
}];

组合网络请求

BatchRequest

JKBaseRequest *request1 = [JKBaseRequest new];
request1.requestUrl = @"/a1";
JKBaseRequest *request2 = [JKBaseRequest new];
request2.requestUrl = @"/a2";
request2.requestMethod = JKRequestMethodPOST;
request2.requestArgument = @{@"name":@"jack"};
JKBatchRequest *batchRequest = [[JKBatchRequest alloc] init];
[batchRequest addRequestsWithArray:@[request1,request2]];
[batchRequest startWithCompletionBlockWithSuccess:^(JKBatchRequest * _Nonnull batchRequest) {
JKBaseRequest *requestA = batchRequest.requestArray.firstObject;
JKBaseRequest *requestB = batchRequest.requestArray.lastObject;
NSLog(@"AAA %@",requestA.responseJSONObject);
NSLog(@"BBB %@",requestB.responseJSONObject);} failure:^(JKBatchRequest * _Nonnull batchRequest) {}];

ChainRequest

1)正常用法

JKBaseRequest *request1 = [JKBaseRequest new];
request1.requestUrl = @"/a1";
request1.responseSerializerType = JKResponseSerializerTypeJSON;
JKBaseRequest *request2 = [JKBaseRequest new];
request2.requestUrl = @"/a2";
request2.requestMethod = JKRequestMethodPOST;
request2.responseSerializerType = JKResponseSerializerTypeJSON;
request2.requestArgument = @{@"name":@"jack"};
JKChainRequest *chainRequest = [JKChainRequest new];
[chainRequest addRequest:request1];
[chainRequest addRequest:request2];
[chainRequest startWithCompletionBlockWithSuccess:^(JKChainRequest * _Nonnull chainRequest) {} failure:^(JKChainRequest * _Nonnull chainRequest) {}];

2)提前结束

JKBaseRequest *request1 = [JKBaseRequest new];
request1.requestUrl = @"/a1";
request1.responseSerializerType = JKResponseSerializerTypeJSON;
JKBaseRequest *request2 = [JKBaseRequest new];
request2.requestUrl = @"/a2";
request2.requestMethod = JKRequestMethodPOST;
request2.responseSerializerType = JKResponseSerializerTypeJSON;
request2.requestArgument = @{@"name":@"jack"};
JKChainRequest *chainRequest = [JKChainRequest new];
[JKChainRequest configNormalRequest:request1 success:^(__kindof JKBaseRequest * _Nonnull request) {// 此处,如果传入参数为NO,那么chainRequest会执行failure 回调;如果传入YES,那么chainRequest会执行success 回调[request1 inAdvanceCompleteGroupRequestWithResult:YES];
} failure:^(__kindof JKBaseRequest * _Nonnull request) {}];[JKChainRequest configNormalRequest:request2 success:^(__kindof JKBaseRequest * _Nonnull request) {// 此处用来处理子网络请求的逻辑
} failure:^(__kindof JKBaseRequest * _Nonnull request) {}];[chainRequest addRequest:request1];
[chainRequest addRequest:request2];
[chainRequest startWithCompletionSuccess:^(JKChainRequest * _Nonnull chainRequest) {} failure:^(JKChainRequest * _Nonnull chainRequest) {}];

PriorityFirstRequest
添加一个网络请求,可以单独的网路请求也可以是一个组合请求,所有的请求必须等到这个优先级网络请求执行完之后才会执行。

1)JKBaseRequest

- (void)priorityFirstRequest
{JKBaseRequest *request = [JKBaseRequest new];request.requestUrl = @"/a1";request.responseSerializerType = JKResponseSerializerTypeJSON;[[JKNetworkAgent sharedAgent] addPriorityFirstRequest:request];
}
  1. JKChainRequest
- (void)priorityFirstRequest2
{JKBaseRequest *request1 = [JKBaseRequest new];request1.requestUrl = @"/a3";request1.responseSerializerType = JKResponseSerializerTypeJSON;JKBaseRequest *request2 = [JKBaseRequest new];request2.requestUrl = @"/a2";request2.requestMethod = JKRequestMethodPOST;request2.responseSerializerType = JKResponseSerializerTypeJSON;request2.requestArgument = @{@"name":@"jack"};JKChainRequest *chainRequest = [JKChainRequest new];[chainRequest addRequest:request1];[chainRequest addRequest:request2];[[JKNetworkAgent sharedAgent] addPriorityFirstRequest:chainRequest];
}
  1. JKBatchRequest
- (void)priorityFirstRequest3
{JKBaseRequest *request1 = [JKBaseRequest new];request1.requestUrl = @"/a3";request1.responseSerializerType = JKResponseSerializerTypeJSON;JKBaseRequest *request2 = [JKBaseRequest new];request2.requestUrl = @"/a2";request2.requestMethod = JKRequestMethodPOST;request2.responseSerializerType = JKResponseSerializerTypeJSON;request2.requestArgument = @{@"name":@"jack"};JKBatchRequest *batchRequest = [JKBatchRequest new];[batchRequest addRequestsWithArray:@[request1,request2]];[[JKNetworkAgent sharedAgent] addPriorityFirstRequest:batchRequest];
}

mock

需要对JKMockManager进行配置,由于这个功能不常用,大家感兴趣的话,可以看看JKMockManager.m 配置字典
有两mock方式,一种是只对使用该网络请求库的请求进行mock,一种可以对所有的网络请请求进行mock,其中第二种方式,下方代码只展示了部分。

对使用该网络请求框架的请求进行mock

- (void)mockRequest
{
[JKNetworkConfig sharedConfig].baseUrl = @"https://www.baidu.com";
[JKNetworkConfig sharedConfig].mockBaseUrl = @"https://123.com/mock/17";
[JKNetworkConfig sharedConfig].isMock = YES;
NSDictionary *config = @{@"GET,/a1":@{}};
[JKMockManager initMockConfig:config];
JKBaseRequest *request = [JKBaseRequest new];
request.requestUrl = @"/a1";
request.responseSerializerType = JKResponseSerializerTypeJSON;
[request startWithCompletionBlockWithSuccess:^(__kindof JKBaseRequest * request) {
NSLog(@"AAA %@",request.responseJSONObject);
} failure:^(__kindof JKBaseRequest * request) {}];
}

对所有的网络请求进行mock

- (void)mockRequest1
{
[JKNetworkConfig sharedConfig].mockBaseUrl = @"https://123.com/mock/17";
[JKNetworkConfig sharedConfig].isMock = YES;
NSDictionary *config = @{@"GET,/a1":@{}};
[JKMockManager initMockConfig:config];
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
configuration.protocolClasses = @[[JKMockURLProtocol class]];
AFHTTPSessionManager *sessionManager = [[AFHTTPSessionManager alloc] initWithSessionConfiguration:configuration];
AFHTTPRequestSerializer *requestSerializer = [AFHTTPRequestSerializer serializer];
sessionManager.securityPolicy = [AFSecurityPolicy defaultPolicy];
sessionManager.responseSerializer = [AFHTTPResponseSerializer serializer];
NSMutableURLRequest *request = [requestSerializer requestWithMethod:@"GET" URLString:@"https://www.baidu.com/a1" parameters:nil error:nil];
NSURLSessionTask *dataTask = [sessionManager dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) {
NSLog(@"AAA %@",responseObject);
}];
[dataTask resume];}

网络请求框架使用外部URL发起请求

1)单个外部网络请求

// 拼接从AppStore获取更新信息的网址NSString *requestUrl = [NSString stringWithFormat:@"https://itunes.apple.com/lookup?id=%@", appId];JKBaseRequest *request = [[JKBaseRequest alloc] init];request.customRequestUrl = requestUrl;request.requestMethod = JKRequestMethodGET;request.requestSerializerType = JKRequestSerializerTypeHTTP;request.responseSerializerType = JKResponseSerializerTypeJSON;[request startWithCompletionSuccess:^(__kindof JKBaseRequest * _Nonnull request) ....

2)一组外部网络请求,如果是同一个供应商,一般域名是相同的可以定义一个JKBaseRequest子类,初始化时将request的baseUrl进行配置即可。

请求添加签名

一般情况下接口都需要添加签名,不同的签名规则,需要创建不同的JKBaseRequest子类
进行签名需要操作的步骤如下:

1)请求对象配置是否需要签名

    JKBaseRequest *request = [[JKBaseRequest alloc] init];request.useSignature = YES;// 子类可以封装在内部初始化中

2)实现JKRequestHelperProtocol中的方法,具体如下:

- (void)signatureRequest:(__kindof JKBaseRequest *)request;
// 在内部实现中,根据request的类根据不同的签名规则进行签名

备注:如果app中只有某一个请求的签名规则和项目中的不太一样,那么没有必要创建子类,可以将签名后的url,赋值给request的customRequestUrl属性。

接口缓存

实现接口缓存需要实现如果操作步骤:

1)如果是客户端开发人员需要指定那个网络请求需要缓存,需要手动指定一下,具体如下:

 JKBaseRequest *request = [[JKBaseRequest alloc] init];request.ignoreCache = NO;// 这个属性默认是NO,也可以不用指定request.cacheTimeInSeconds = 30;//cacheTimeInSeconds大于0的时候才会对返回内容进行缓存

2)如果api有下发指定哪些接口需要缓存,api下发的需要缓存的接口可能客户端开发者指定的有冲突,重叠。具体需要根据业务讨论一个优先级准则。需要实现JKRequestHelperProtocol中如下方法:

- (void)judgeToChangeCachePolicy:(__kindof JKBaseRequest *)request;
//内部根据条件判断是否需要改变相应网络请求的缓存配置

3)具体实现缓存的操作,实现JKRequestHelperProtocol协议方法如下:

/// load Cache data of the request
/// @param request request
- (id)loadCacheDataOfRequest:(__kindof JKBaseRequest *)request error:(NSError **)error/// save the request's reponse to cache
/// @param request request
- (void)saveResponseToCacheOfRequest:(__kindof JKBaseRequest *)request/// clear the the request's response from cache
/// @param request request
- (void)clearResponseFromCacheOfRequest:(__kindof JKBaseRequest *)request

动态域名更换

实现不动态域名更换,需要实现JKRequestHelperProtocol中的如下方法:

/// get the baseUrl of the request
/// @param request request
- (NSString *)baseUrlOfRequest:(__kindof JKBaseRequest *)request

请求url配置公共参数

需要实现JKRequestHelperProtocol中的如下方法:

/// this is the url append or filter func
/// @param originUrl originUrl
/// @param request request
- (NSString *)filterUrl:(NSString *)originUrl withRequest:(__kindof JKBaseRequest *)request;

网络请求返回数据解析在子线程执行

网络请求成功后,数据转换成模型是一个耗时操作,将该操作放在子线程执行可以减少主线程的拥堵,具体操作如下:

/// start the request
/// @param parseBlock the block used to parse response, exec not in mainThread
/// @param successBlock successBlock
/// @param failureBlock failureBlock
- (void)startWithCompletionParse:(nullable id(^)(__kindof JKBaseRequest *request, NSRecursiveLock *lock))parseBlocksuccess:(nullable void(^)(__kindof JKBaseRequest *request))successBlockfailure:(nullable void(^)(__kindof JKBaseRequest *request))failureBlock;

备注:JKBaseRequest或者其子类的对象调用该方法,并在parseBlock中将数据解析然后返回,这个返回值会赋给request的parsedData,开发者可以接着在successBlock中使用这个数据刷新UI(successBlock已经返回到主线程),如果用到了block以外的数据,需要用block中传递过来的lock,加锁,解锁。另外一个需要注意点就是这个parseBlock是在并发子线程执行,不能调用任何和UI相关的API。

文档地址:https://github.com/xindizhiyin2014/JKNetworking
备注:文档后期会根据迭代更新

cocopods引入项目

pod 'JKNetworking_'

JKNetworking完整文档相关推荐

  1. openlayers5之完整文档v5.1.3.zip下载

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/gisdoer/article/details/81697967 openlayers完整文档v5.1 ...

  2. Spring 2.5 jar 所有开发包及完整文档及项目开发实例

    Spring 2.5 jar 所有开发包及完整文档及项目开发实例 spring jar 包详解spring.jar是包含有完整发布的单个jar包,spring.jar中包含除了 spring-mock ...

  3. 大型三甲医院云HIS系统源码 强大的电子病历+完整文档

    医院HIS系统源码云HIS系统:SaaS运维平台+多医院入驻+强大的电子病历+完整文档 有源码,有演示 一.系统概述 Ø 采用主流成熟技术,软件结构简洁.代码规范易阅读,SaaS应用,全浏览器访问前后 ...

  4. 【源码分享】ASP.NET大型快运(快递)管理系统带完整文档

    ASP.NET大型快运(快递)管理系统源码带完整文档 大型快递(快运)管理系统基于webservice的分布式系统,集成快递物流业务流程管理,快递物流公司内部管理,快递物流单全网跟踪监控,并集成基于w ...

  5. (运动会模拟射靶)Python期末大作业(附完整文档)

    python期末大作业,因为是数据分析与可视化,所以我在网上搜索的时候,找到了一篇关于大作业射靶的题目,原文写的很好,也提供了下载,本篇在其基础上增加了数据可视化-图表,并且增加了,方差,个人平均分在 ...

  6. ASP.NET大型快运(快递)ERP系统带完整文档【源码分享】

    ASP.NET大型快运(快递)管理系统源码带完整文档 源码分享,需要源码学习参考可私信我. 大型快递(快运)管理系统基于webservice的分布式系统,集成快递物流业务流程管理,快递物流公司内部管理 ...

  7. 敏感词“智能”检测(代码和完整文档在最后)

    完整文档下载 案例代码下载

  8. 完整版H5社交聊天平台源码[完整数据库+完整文档教程]

    介绍: 开发语言:PHP 数据库:MySQL 完整版H5社交聊天平台源码:一款优化了的版本,带有完善的文档教程和完整数据库文件. 东西非常的齐全,这款是客户定制的,所以东西很完整,也值不少钱,源码开发 ...

  9. 可打包app的H5社交及时通讯平台完整版源码[完整数据库+完整文档教程]

    源码简介: 这套即时通讯源码价值4000元!全原生,从底层开始结构就完全不一样,mongodb的库,uniapp混编手端,二开难度要比视酷或者酷信容易很多.全开源,带开发文档.前端用的是uniapp技 ...

最新文章

  1. qml学习笔记(二):可视化元素基类Item详解(上半场anchors等等)
  2. nginx php-fpm 运行原理
  3. python一次性读取整个文件-python-文件中的行是否读取整个文件
  4. VMware虚拟机中,RHEL系统下挂载、卸载新硬盘的方法
  5. 图像中添加二项式分布噪声
  6. pat 乙级 1014 福尔摩斯的约会 (C++)
  7. readdirectorychangesw 链接错误 undeclared identifier 解决方法
  8. CDH 5.13.0 集成 Phoenix
  9. 熊孩子倾家荡产玩游戏、打赏主播有救了!最高法:无效,可退还
  10. java输出string变量名_java – 从String获取名称变量
  11. GE HYDRAN M2 IS200VCRCH1B IS200VRTDH1D IS200VTCCH1CBB IS200VTURH2BAC IS215VPROH1BD IS220PAICH2A
  12. Java类的三大特性
  13. 这是一个价值一个亿的项目思维导图
  14. 我爱淘二次冲刺阶段5
  15. 账号被盗,如何强制下线?
  16. 基于最大熵Maxent-ArcGis地理分布预测教程
  17. 如何自学单片机? 单片机怎么入门?
  18. 向工信部投诉中国联通、移动、电信等运营服务商的权威途径
  19. Android自定义一个View实现运动的小人
  20. 一、Unity环境安装

热门文章

  1. [读书笔记]5个小技巧让你写出更好的JavaScript[图]
  2. 微信小程序云开发|个人博客小程序
  3. 平台服务器型号,云平台服务器型号
  4. 奥克兰oracle,IEM奥克兰前瞻: 顶级战队决战甲骨文中心
  5. 简析项目中常用的七参数转换法和四参数转换法以及涉及到的基本测量学知识...
  6. UVA 1471 Defense Lines 防线
  7. 服装管理系统大一c语言
  8. 基于ZigBee技术的无线抄电表系统设计(1)
  9. 为什么苹果日历不能设置日程_苹果日历怎么用 苹果日历使用方法介绍
  10. 关于 allegro的pcbEditor在使用过程中经常卡或者busy无响应 的解决方法