CBNetworking AFN的封装,别出心裁
为什么要对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的封装,别出心裁相关推荐
- IOS开发基础之网易新闻环境搭建异步请求json,AFN网络封装第1天
IOS开发基础之网易新闻环境搭建异步请求json,AFN网络封装第1天 视频资料是2015年的,但是AFN是导入框架的关键文件,我尝试使用cocoapods安装最新的AFN,虽然成功了,但是版本太高, ...
- afn访问本地html,Swift利用AFN实现封装网络请求详解
前言 相信大家都知道,我们一般在一个项目中,网络请求都封装成一个单例,以确保整个项目的网络请求 Session 是同一个. 单例模式定义:一个类有且仅有一个实例,并且自行实例化向整个系统提供,下面话不 ...
- ASI与AFN网络请求的的比较
对比 ASI AFN 更新状态 2012年10月份,已经停止更新 持续更新中,目前已更新至3.0版 介绍 ASI的直接操作对象 ASIHTTPRequest,是一个实现了了NSCopying协议的NS ...
- 李洪强经典面试题10
1. 客户端安全性处理方式? 1> 网络数据传输(敏感数据[账号\密码\消费数据\银行卡账号], 不能明文发送) 2> 协议的问题(自定义协议, 游戏代练) 3> ...
- AFNetworking 学习笔记
上图来自 @mattt 对 AFN 的介绍:Everybody Loves AFNetworking And So Can You!. 学习 AFN,简单记录一下以加深自己理解. AFN 的基础部分是 ...
- 从此走上一条iOS程序猿不归路。。。
新的城市,新的生活!前不久刚刚结束了苦逼的面试找工作之旅,期间也小有收货,如今正处年底工作闲暇之余,将前一阵子陆陆续续的总结整理了一下,本人菜鸟程序猿一只,水平有限,本文总结的知识不算深入,比较浅显, ...
- iOS简历这样写,才能找到好工作
近几年来,iOS开发人员越来越多,而职场要求越来越高.对于职场来说,简历就如同门面.若是没想好,出了差错,耽误些时日倒不打紧,便是这简历入不了HR的眼,费力伤神还不能觅得好去处,这数年来勤学苦练的大好 ...
- IOS-小项目(饿了么 网络部分 简单实现)
在介绍小项目之前,在此说明一下此代码并非本人所写,我只是随笔的整理者. 在介绍之前先展现一下效果图. 看过效果图大家应该很熟悉了,就是饿了么的一个界面而已,值得注意的是,实现时并没有采用本地连接,而是 ...
- 主要责任、 主要技术
主要责任.主要技术 责任描述: 协助项目经理对产品进行构架, 软件界面架构及实现,多控制器嵌套处理 利用UI设计组提供的UI图片,使用AutoLayout布局设置对APP界面进 ...
最新文章
- 阿里某程序员吐槽:年终奖被金融行业的老婆完爆!自己奖金15万,老婆奖金66万!...
- html大文件占用内存,[Flutter] 大文件上传之随传随处理(避免占用大量内存)
- JavaWeb中连接数据库的一般方式与通过JNDI连接池的方式
- 什么?欧洲也有个恩智浦杯?
- WEB开发之如何改善PHP开发方式
- Linux_LAMP 最强大的动态网站解决方案
- java王子救公主的游_计蒜客 王子救公主(DFS)
- THINKPHP聊天软件H5实时聊天室自动分配账户全开源商业源码
- jquery-显示隐藏-链式调用
- Spring框架:跨域问题之使用@CrossOrigin注解解决失败的原因总结
- Array flat
- 鸿蒙os事例代码,鸿蒙HarmonyOS App开发造轮子之自定义圆形图片组件的实例代码
- IBM软件三大发力点推进“软”实力着陆中国
- 9月29日见?华为nova 9系列配置细节曝光:最高支持100W快充
- 树——二叉树结点的删除与清除
- myeclipse 8.5安装freemarker插件方法
- 人脸识别 数据集 与竞赛
- 学习《医学三字经白话解》之虚劳
- CMake工程从入门到进阶完整版,可以完成简单的工程创建(完结)
- 开源交通仿真平台SimMobility的安装教程
热门文章
- 手机java淘汰_极客修:对手并不止安卓!这些年iOS竟然把这么多手机系统淘汰掉了...
- 贪心题集(vjoj)
- 计算机数字键盘无法输入数字,电脑数字键打不出数字怎么办?电脑数字键打不出数字的修复方法...
- matlab 渐变色
- Web APIS Xmind
- gtk之G_LIKELY(expr)和G_UNLIKELY(expr)
- 智慧树课程问答怎么得分
- 小白学SLAM的流水账(一):跑通ORB踩过的坑
- 中国支付清算协会发布《2022中国支付清算行业社会责任报告》
- python3连接mysql获取ansible动态inventory脚本