iOS封装AFNetworking3.0网络请求,进行本地数据缓存,json格式验证

在ios开发中,网络请求是比不缺少的一部分,做开发的绝大多数都是用的是AFNetworking框架,因为它简单好上手,很多网络方法是直接调用的,但是面对各种业务需求如何将网络请求更好的封装起来是我们值得好好考虑的。不得不说猿题库网络请求确实把AFN封装的挺好的,基本上项目上的需求它都能实现并且还有好多高级功能,我就不在这介绍猿题库的网络请求怎么样厉害了,猿题库网络请求demo 有兴趣的同学可以研究下。

今天就想跟大家分享一下我做网络请求缓存到本地的思路。做网络缓存呢为的就是优化用户体验,减少用户对接口的请求节省流量。下面说一下我的思路:

  • 数据请求下来怎么存

  • 如何设置缓存的时间

  • 数据存储的类型,比如写缓存不读缓存等

  • 读取缓存数据,如何区分

  • 数据错误处理

  • 上拉刷新强制更新数据,下拉加载是读缓存还是重新请求

  • 对于一些接口需要重复请求处理 比如:视频列表多次点击上传用户记录等

可能你的网络请求是这样的:

+ (void)request:(NSString *)urlString withParamters:(NSDictionary *)dic success:(void (^)(id responseData))success failure:(void (^)(NSError *error))failure;

发起一个网络请求,使用的时候urlStr基本上就是固定的用宏来定义的。dic就是传递的字典.success 和failure 分别表示请求成功和失败的回调

像比如上传播放记录等什么的,上面那个方法里面有提示视图(MBProgressHUD),上传记录肯定不能调用那个方法,因为有提示图啊,用户一切换视频什么的提示记录上传成功,那肯定不行吧,那就在写一个没有提示的方法比如这个:

+ (void)requestNoProgress:(NSString *)urlString withParamters:(NSDictionary *)dic success:(void (^)(id responseData))success failure:(void (^)(NSError *error))failure;

或许项目中有的地方需要POST请求,有的需要GET请求或者HTTPS请求,光写方法就需要4-5个,这样问题就很突出而且很麻烦。其实,我自己在项目中就是这样写的。哈哈

我重新将网络请求整理了一下,加入了缓存和json字段检验,后期肯定还要加很多东西,更改的同时会一并更新到GitHub上。demo下载地址

简单说一下代码结构,主要就三个MNetSetting网络请求设置类MNetworkUtils网络请求工具类MNetRequestModel网络请求,负责请求数据。其实分成三个文件去写为了就是减少代码的冗余度增加可读性(其实代码很渣)。

先来看一下,demo中网络请求是怎么用的:

    MNetSetting *set = [[MNetSetting alloc]init];
    set.isHidenHUD = YES;//隐藏提示图
    set.cashSeting = MCacheSave;//进行缓存,默认缓存时间3分钟
    set.cashTime = 5;//缓存时间5分钟
    //进行json格式验证,可以写可不写
    set.jsonValidator = @{@"entity":[NSDictionary class],
                          @"entity":@{@"indexCenterBanner":[NSArray class]}
                          };
    [set requestDataFromHostURL:@"请求地址,必传" andParameter:@"参数,可不传" success:^(id responseData) {
    //数据请求成功回调
    } failure:^(NSError *error) {
     //失败回调   
    } //传入网络请求缓存策略设置
    netSeting:set];

再来说一下MNetSetting这个类:

这个里面主要就是对网络请求的整体配置了。分别有两个枚举MCashTime设置缓存策略 MRequesttMethod网络请求方式,POST和GET;枚举也没写几个,因为暂时想到的也只有这么多,大部分写的是属性。简单说下属性:

/** *是否显示HUD,默认显示*/
@property (nonatomic, assign) BOOL isHidenHUD;
/** *是否是HTTPS请求,默认是NO*/
@property (nonatomic, assign) BOOL isHttpsRequest;
/** *缓存设置策略*/
@property (nonatomic, assign) MCashTime cashSeting;
/** *是否刷新数据*/
@property (nonatomic, assign) BOOL isRefresh;
/** *是否读取缓存*/
@property (nonatomic, assign) BOOL isReadCash;
/** *缓存时间*/
@property (nonatomic, assign) NSInteger cashTime;
/** *请求方式,默认POST请求*/
@property (nonatomic, assign) MRequesttMethod requestStytle;
/** *地址*/
@property (nonatomic, strong) NSString *hostUrl;
/** *参数*/
@property (nonatomic, strong) NSDictionary *paramet;
/** *验证json格式*/
@property (nonatomic, strong) id jsonValidator;

只有一个网络请求方法:

/**
 通过url获取数据或获取缓存数据

 @param url 请求地址
 @param parameter 参数
 @param success 成功回调
 @param failure 失败回调
 @param seting 网络请求设置
 */
-(void)requestDataFromHostURL:(NSString *)url
             andParameter:(NSDictionary *)parameter
                  success:(void (^)(id responseData))success
                  failure:(void (^)(NSError *error))failure
                  netSeting:(MNetSetting *)seting;

当整理这些东西的时候都在想,这些数据我以什么样的方式去缓存到本地呢。第一个就将plist文件排除在外,因为plist文件是覆盖性的存一次还要将以前存的文件都拿出来再放回去,麻烦。在网上简单查了一下有人用fmdb和sqlite 感觉存个数据就要动用数据库是不是闹的动静有点大,想来想起还是用归档和解档将数据以文件形式存入本地。所以上面写的:数据请求下来怎么存的问题解决了

现在考虑如何设置缓存时间,可能MNetSetting这个里面的属性也看了,可以调用属性设置缓存时间,3分钟,5分钟,1天等,自主设置;

数据存储的类型;上拉刷新强制更新数据,下拉加载是读缓存还是重新请求;加载数据写缓存,上拉加载更多不读缓存 这些都是通过属性去设置的

数据错误处理 项目中经常有一些数据的类型判断,比如:返回数据的entity是字典还是数组,在项目中或许你经常是这样写的

if ([responseData[@"entity"] isKindOfClass:[NSArray class]]){
     ....
  }

如果不这样写,过分依赖接口返回的数据可能会因数据类型不对导致程序崩溃.如果这样写而需要在每个接口返回的数据中都要加if判断,很麻烦而且可读性也不高。我在demo中加入了,json返回数据的类型判断,这样就避免了每次去写判断,在进行缓存时也不会缓存错误数据。这里的json类型判断是参考猿题库写的,json类型判断你可以这样用:

MNetSetting *set = [[MNetSetting alloc]init];
set.isHidenHUD = YES;
// indexCenterBanner 是entity的下级
set.jsonValidator = @{
                    @"entity":[NSDictionary class],
                    @"entity":@{@"indexCenterBanner":[NSArray class]}
                     };

缓存的读取是根据本地缓存数据创建的时间与请求时间相比对来决定是取本地缓存还是重新请求接口。文件创建时间是根据文件管理器NSFileManager来获取的,获取文件创建时间,是一个NSDate类型:

NSString *path = [self cacheFilePath];
NSError * error;
NSFileManager *fileManager = [NSFileManager defaultManager];
//通过文件管理器来获得属性
NSDictionary *fileAttributes = [fileManager attributesOfItemAtPath:path error:&error];
NSDate *fileCreateDate = [fileAttributes objectForKey:NSFileCreationDate];

比较两个文件时间来决定是否读取缓存:

NSComparisonResult result = [currentDate compare:fileDate]; 
//NSOrderedDescending 降序排列 说明文件创建时间超过当前时间,刷新数据
//NSOrderedAscending 升序 说明 文件创建时间小于当前时间,返回缓存数据

东西不是很多,主要就是说一下思路以及对接口请求下来的数据做json验证处理。demo中也都有注释,有一些具体细节可以看一下demo。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,012评论 4 359
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,589评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,819评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,652评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,954评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,381评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,687评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,404评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,082评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,355评论 2 241
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,880评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,249评论 2 250
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,864评论 3 232
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,007评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,760评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,394评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,281评论 2 259

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,087评论 18 139
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 11,595评论 4 59
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,544评论 25 707
  • 时间:2017年7月18日 星期二 地点:卡乐咪牧笛儿童之家室内 活动内容:工作时间 美好的一天结束了,明天见!
    梦与自由阅读 201评论 0 0
  • 昨夜做梦时候,梦见该是礼佛的日子,急匆匆的买水果时。在水果摊旁见到一棵很高很高的树,树上挂满红丝带。旁边水果摊的...
    苜蓿partlia阅读 324评论 0 1