为什么要对AFNetworking进行多一层的封装

对于AFNetworking进行二次封装是很有必要的。事实上,在项目中大量使用第三方网络库是有风险的,因为网络请求的使用遍布整个应用,而一旦该对应的网络库不再更新维护,或者我们有意愿的去更换网络框架,修改将会有着巨大的难以承受的工作量。

这一个框架与其他框架有什么不同

  • 本框架基于AFNetworking3.0的版本进行封装,面向更新的版本。

  • 为网络请求的任务管理做了大量的工作,使得下载上传,或者其他使用环境下的任务管理得以更轻松的实现。

  • 反其道而行,专为Post请求作出了缓存处理,这一部分缓存处理的使用与否,由使用者自行决定。

  • 自定义Get请求的缓存策略,以时间为基准,严格把控缓存的有效性。

接口设计

请求

这里使用了新建NS_ENUM的方式来统一Post和Get接口。

/***  请求方式*/
typedef NS_ENUM(NSInteger, CBRequestType) {/***  POST方式来进行请求*/CBPOSTRequest = 1 << 0,/***  GET方式来进行请求*/CBGETRequest  = 1 << 1
};
/***  统一请求接口**  @param url              请求路径*  @param params           拼接参数*  @param httpMethod       请求方式(0为POST,1为GET)*  @param useCache         是否使用缓存*  @param progressBlock    进度回调*  @param successBlock     成功回调block*  @param failBlock        失败回调block**  @return 返回的对象中可取消请求*/
+ (CBURLSessionTask *)requestWithUrl:(NSString *)urlparams:(NSDictionary *)paramsuseCache:(BOOL)useCachehttpMedthod:(CBRequestType)httpMethodprogressBlock:(CBNetWorkingProgress)progressBlocksuccessBlock:(CBResponseSuccessBlock)successBlockfailBlock:(CBResponseFailBlock)failBlock;

从上面的代码我们可以看到,参数useCache决定着你是否使用Post请求的缓存功能,而即便将其设置为NO,依然会自动开启Get请求的缓存功能。

数据解析方式

/***  数据串行方式*/
typedef NS_ENUM(NSInteger, CBSerializerType) {/***  HTTP方式来进行请求或响应*/CBHTTPSerializer = 1 << 0,/***  JSON方式来进行请求或响应*/CBJSONSerializer = 1 << 1
};
/***  更新请求或者返回数据的解析方式(0为HTTP模式,1为JSON模式)**  @param requestType  请求数据解析方式*  @param responseType 返回数据解析方式*/
+ (void)updateRequestSerializerType:(CBSerializerType)requestTyperesponseSerializer:(CBSerializerType)responseType;

上面的NS_ENUM联合上面的方法可以更改数据解析方式,更具灵活性。

文件上传,下载

/***  文件上传接口**  @param url              传文件接口地址*  @param uploadingFile    上传文件路径*  @param progressBlock    上传进度*  @param successBlock     成功回调*  @param failBlock        失败回调**  @return 返回的对象中可取消请求*/
+ (CBURLSessionTask *)uploadFileWithUrl:(NSString *)urluploadingFile:(NSString *)uploadingFileprogressBlock:(CBNetWorkingProgress)progressBlocksuccessBlock:(CBResponseSuccessBlock)successBlockfailBlock:(CBResponseFailBlock)failBlock;
/***  文件下载接口**  @param url           下载文件接口地址*  @param saveToPath    存储目录*  @param progressBlock 下载进度*  @param successBlock  成功回调*  @param failBlock     下载回调**  @return 返回的对象可取消请求*/
+ (CBURLSessionTask *)downloadWithUrl:(NSString *)urlsaveToPath:(NSString *)saveToPathprogressBlock:(CBNetWorkingProgress)progressBlocksuccessBlock:(CBResponseSuccessBlock)successBlockfailBlock:(CBResponseFailBlock)failBlock;

针对文件的下载和上传的做出专门的设计。

任务管理

由上面的方法中,我们可以看到每一个方法都返回了一个任务对象CBURLSessionTask,这个对象继承于NSURLSessionTask,如此我们可以直接的取到每次进行任务请求的对象,直接对其进行管理。但不止于此,我仍然写了以下的几个接口来更快捷更集中的对其进行管理。

/***  取消所有请求*/
+ (void)cancelAllRequest;
/***  根据url取消请求**  @param url 请求url*/
+ (void)cancelRequestWithURL:(NSString *)url;

通过这两个方法,我们可以直接取消所有的请求,或者取消单个链接对应的请求。全局性的执行取消操作,更方便。

缓存处理

Post缓存处理

由于苹果官方的NSURLCache不支持Post请求的缓存处理,所有这一部分的缓存处理,我自己通过归档的方式来进行管理。

主要的方法如下:

+ (id)getCacheResponseWithURL:(NSString *)urlparams:(NSDictionary *)params {id cacheData = nil;if (url) {NSString *directoryPath = DIRECTORYPATH;NSString *originString = [NSString stringWithFormat:@"%@+%@",url,params];NSString *path = [directoryPath stringByAppendingPathComponent:[self md5:originString]];NSData *data = [[NSFileManager defaultManager] contentsAtPath:path];if (data) {cacheData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];}}return cacheData;
}
+ (void)cacheResponseObject:(id)responseObjectrequest:(NSURLRequest *)requestparams:(NSDictionary *)params {if (request && responseObject && ![responseObject isKindOfClass:[NSNull class]]) {NSString *directoryPath = DIRECTORYPATH;NSError *error = nil;if (![[NSFileManager defaultManager] fileExistsAtPath:directoryPath isDirectory:nil]) {[[NSFileManager defaultManager] createDirectoryAtPath:directoryPathwithIntermediateDirectories:YESattributes:nilerror:&error];}NSString *originString = [NSString stringWithFormat:@"%@+%@",request.URL.absoluteString,params];NSString *path = [directoryPath stringByAppendingPathComponent:[self md5:originString]];NSDictionary *dict = (NSDictionary *)responseObject;NSData *data = nil;if ([dict isKindOfClass:[NSData class]]) {data = responseObject;} else {data = [NSJSONSerialization dataWithJSONObject:dictoptions:NSJSONWritingPrettyPrintederror:&error];}if (data && error == nil) {[[NSFileManager defaultManager] createFileAtPath:path contents:data attributes:nil];}}
}+ (NSString *)md5:(NSString *)string {if (string == nil || [string length] == 0) {return nil;}unsigned char digest[CC_MD5_DIGEST_LENGTH], i;CC_MD5([string UTF8String], (int)[string lengthOfBytesUsingEncoding:NSUTF8StringEncoding], digest);NSMutableString *ms = [NSMutableString string];for (i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {[ms appendFormat:@"%02x", (int)(digest[i])];}return [ms copy];
}

值得注意的是,每一次进行缓存,都通过HASH的方式对缓存进行了加密,从而达到唯一缓存和更加安全的目的。

Get请求的自定义

按道理,官方已经对于Get请求进行了很完善的缓存处理,为什么我还要自行处理呢?事实上,我并没有自定义这一部分的处理,我仅对于NSURLCache加多了一层封装,从而达到自定义策略的目的,主要的方法如下所示:

- (id)cachedResponseForRequest:(NSURLRequest *)request {NSCachedURLResponse *cachedResponse = [super cachedResponseForRequest:request];if (cachedResponse) {NSDate *cacheDate = cachedResponse.userInfo[CBURLCacheExpirationKey];NSDate *cacheExpirationDate = [cacheDate dateByAddingTimeInterval:CBURLCacheExpirationInterval];if ([cacheExpirationDate compare:[NSDate date]] == NSOrderedAscending) {[self removeCachedResponseForRequest:request];return nil;}}id responseObj = [NSJSONSerialization JSONObjectWithData:cachedResponse.data options:NSJSONReadingAllowFragments error:nil];return responseObj;
}
- (void)storeCachedResponse:(id)responseresponseObjc:(id)responseObjcforRequest:(NSURLRequest *)request {NSData *data = [NSJSONSerialization dataWithJSONObject:responseObjc options:NSJSONWritingPrettyPrinted error:nil];NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];userInfo[CBURLCacheExpirationKey] = [NSDate date];NSCachedURLResponse *modifiedCachedResponse = [[NSCachedURLResponse alloc] initWithResponse:response data:data userInfo:userInfo storagePolicy:0];[super storeCachedResponse:modifiedCachedResponse forRequest:request];
}

小结

更详细的代码请大家点击下载查看,谢谢大家的关注,如果可以,请点个star支持一下,谢谢。

CBNetworking AFN的封装,别出心裁相关推荐

  1. IOS开发基础之网易新闻环境搭建异步请求json,AFN网络封装第1天

    IOS开发基础之网易新闻环境搭建异步请求json,AFN网络封装第1天 视频资料是2015年的,但是AFN是导入框架的关键文件,我尝试使用cocoapods安装最新的AFN,虽然成功了,但是版本太高, ...

  2. afn访问本地html,Swift利用AFN实现封装网络请求详解

    前言 相信大家都知道,我们一般在一个项目中,网络请求都封装成一个单例,以确保整个项目的网络请求 Session 是同一个. 单例模式定义:一个类有且仅有一个实例,并且自行实例化向整个系统提供,下面话不 ...

  3. ASI与AFN网络请求的的比较

    对比 ASI AFN 更新状态 2012年10月份,已经停止更新 持续更新中,目前已更新至3.0版 介绍 ASI的直接操作对象 ASIHTTPRequest,是一个实现了了NSCopying协议的NS ...

  4. 李洪强经典面试题10

    1.     客户端安全性处理方式? 1>   网络数据传输(敏感数据[账号\密码\消费数据\银行卡账号], 不能明文发送) 2>   协议的问题(自定义协议, 游戏代练) 3>   ...

  5. AFNetworking 学习笔记

    上图来自 @mattt 对 AFN 的介绍:Everybody Loves AFNetworking And So Can You!. 学习 AFN,简单记录一下以加深自己理解. AFN 的基础部分是 ...

  6. 从此走上一条iOS程序猿不归路。。。

    新的城市,新的生活!前不久刚刚结束了苦逼的面试找工作之旅,期间也小有收货,如今正处年底工作闲暇之余,将前一阵子陆陆续续的总结整理了一下,本人菜鸟程序猿一只,水平有限,本文总结的知识不算深入,比较浅显, ...

  7. iOS简历这样写,才能找到好工作

    近几年来,iOS开发人员越来越多,而职场要求越来越高.对于职场来说,简历就如同门面.若是没想好,出了差错,耽误些时日倒不打紧,便是这简历入不了HR的眼,费力伤神还不能觅得好去处,这数年来勤学苦练的大好 ...

  8. IOS-小项目(饿了么 网络部分 简单实现)

    在介绍小项目之前,在此说明一下此代码并非本人所写,我只是随笔的整理者. 在介绍之前先展现一下效果图. 看过效果图大家应该很熟悉了,就是饿了么的一个界面而已,值得注意的是,实现时并没有采用本地连接,而是 ...

  9. 主要责任、 主要技术

    主要责任.主要技术 责任描述:     协助项目经理对产品进行构架,     软件界面架构及实现,多控制器嵌套处理     利用UI设计组提供的UI图片,使用AutoLayout布局设置对APP界面进 ...

最新文章

  1. 阿里某程序员吐槽:年终奖被金融行业的老婆完爆!自己奖金15万,老婆奖金66万!...
  2. html大文件占用内存,[Flutter] 大文件上传之随传随处理(避免占用大量内存)
  3. JavaWeb中连接数据库的一般方式与通过JNDI连接池的方式
  4. 什么?欧洲也有个恩智浦杯?
  5. WEB开发之如何改善PHP开发方式
  6. Linux_LAMP 最强大的动态网站解决方案
  7. java王子救公主的游_计蒜客 王子救公主(DFS)
  8. THINKPHP聊天软件H5实时聊天室自动分配账户全开源商业源码
  9. jquery-显示隐藏-链式调用
  10. Spring框架:跨域问题之使用@CrossOrigin注解解决失败的原因总结
  11. Array flat
  12. 鸿蒙os事例代码,鸿蒙HarmonyOS App开发造轮子之自定义圆形图片组件的实例代码
  13. IBM软件三大发力点推进“软”实力着陆中国
  14. 9月29日见?华为nova 9系列配置细节曝光:最高支持100W快充
  15. 树——二叉树结点的删除与清除
  16. myeclipse 8.5安装freemarker插件方法
  17. 人脸识别 数据集 与竞赛
  18. 学习《医学三字经白话解》之虚劳
  19. CMake工程从入门到进阶完整版,可以完成简单的工程创建(完结)
  20. 开源交通仿真平台SimMobility的安装教程

热门文章

  1. 手机java淘汰_极客修:对手并不止安卓!这些年iOS竟然把这么多手机系统淘汰掉了...
  2. 贪心题集(vjoj)
  3. 计算机数字键盘无法输入数字,电脑数字键打不出数字怎么办?电脑数字键打不出数字的修复方法...
  4. matlab 渐变色
  5. Web APIS Xmind
  6. gtk之G_LIKELY(expr)和G_UNLIKELY(expr)
  7. 智慧树课程问答怎么得分
  8. 小白学SLAM的流水账(一):跑通ORB踩过的坑
  9. 中国支付清算协会发布《2022中国支付清算行业社会责任报告》
  10. python3连接mysql获取ansible动态inventory脚本