美文网首页
setValue-forKey小记

setValue-forKey小记

作者: 雨Yuki | 来源:发表于2017-10-17 17:21 被阅读14次

关于NSObject的setValue forKey的一个小tip

这两天重构项目的认证接口,接口的大概功能是,要根据每个字段的值去判断
每个认证的状态,接口的返回值大概是这样的。。。。。。

{
code = 0;
data =     {
button = 1;
contact = 1;
credential = 0;
"credit_indicator" = 243;
housingfund = 0;
idcard = 1;
information = 0;
isp = 0;
jingdong = 0;
"loan_history" = 0;
report = 0;
taobao = 0;
time = "2017-08-01T11:18:52.000+08:00";
zhima = 1;
"zhima_certifications" = 1;
};
"reset_data" =     (
);
"update_prompt" =     (
{
identity = 0;
},
{
contact = 1;
}
);
}

我来解释一下这个返回数据,data里的0和1的那些字段每个对应一个认证,1表示已认证,0为未认证。
reset_data和update_prompt都是数组,数组里的元素一个字典,字典里的字段对应一个认证。
reset_data里的字典如果包含某个字段,则该认证状态为已过期。
update_prompt里的字典如果包含某个字段,并且值为1,则该认证状态为可更新,例如contact,否则为已更新,例如identity

这个逻辑是不是很奇葩。。。其实完全可以用"字段"=1或者2、3这样表示
每个认证的状态,例如:1未认证2已认证3已过期4可更新5已更新
(别问我接口后台谁写的,我也很绝望啊)

以前的数据解析是这样的。。。

if (dict[@"carrier"]) {
if ([dict[@"carrier"] intValue] == 1) {
[defaults setObject:@"3" forKey:@"SERVICEShine"];
}else{
[defaults setObject:@"4" forKey:@"SERVICEShine"];
}
}else if (dict[@"taobao"]) {
if ([dict[@"taobao"] intValue] == 1) {
[defaults setObject:@"3" forKey:@"TBShine"];
}else{
[defaults setObject:@"4" forKey:@"TBShine"];
}
} ....此处省略无数个if else

单单一个数据解析写了近200行,然后还在多处地方用到。。。对于有技术追求的我们,怎么能这么干呢?

果断重构之,方案如下:

新建一个model类,创建一个枚举类型,表示认证的每种状态

typedefNS_ENUM(NSInteger, NAAuthenticationState) {

    NAAuthenticationStateNot =0,// 未认证

    NAAuthenticationStateAlready,// 已认证

    NAAuthenticationStateOverdue,// 已过期

    NAAuthenticationStateCanUpdate,// 可更新

    NAAuthenticationStateAlreadyUpdate// 已更新

};

添加data中的每个key作为属性,此类有3个方法:

  • 单例+ (instancetype)sharedModel;

  • 获取所有属性名+ (NSArray*)getAllProperties;

  • 然后是解析方法+ (void)analysisAuthentication:(NSDictionary*)returnValue;
    解析方法的实现具体也分3步,因为坑爹的返回数据格式。

返回数据分三部分,为了方便理解,我们命名为dataDic、resetArr、updateArr,数据类型应该一目了然吧。

1. dataDic

首先利用第三方库YYModel对dataDic字典里的数据进行model转换

[model yy_modelSetWithJSON:dataDic];
这里刚好0代表未认证,1代表已认证,所以这一句就够了。

2. resetArr

然后遍历数组resetArr,再遍历里面的字典进行赋值,由于这里的数据value还都是0,我们需要的值是NAAuthenticationStateOverdue,也即是2,而且有个别key居然跟上一步的命名不一样。。。所以不能直接用yymodel赋值了。
我们选择在遍历字典时,先把不一样的key单独找出来赋值成NAAuthenticationStateOverdue,然后其他的利用setValueforKey进行赋值

重点来了
setValueforKey的value必须为id类型,而我们的属性是枚举类型,也即是NSInteger,这样用会报错,怎么办呢?
id propertyValue = [[[NSNumberFormatter alloc] init] numberFromString:@"2"];
这样我们再用setValueforKey就没问题了,完美~

3. updateArr

跟第二步类似


到此解析完成,这样我们就算是在很多地方用到,只需要引入此model,调用解析方法即可,简洁美观~


哦,对了还有一点,至于为什么不像旧的那样,用NSUserDefaults保存本地,我认为是没有必要的。

因为这些数据在用到的时候,都会提前请求更新一下,本地保存完全没有意义,故用单例保存足以。

附上Demo ,如果您感觉有一点点用的话,请帮忙star一下,谢谢啦~

相关文章

  • setValue-forKey小记

    关于NSObject的setValue forKey的一个小tip 这两天重构项目的认证接口,接口的大概功能是,要...

  • Web版扫雷开发小记(3)

    前篇: web版扫雷开发小记(1)web版扫雷开发小记(2)web版扫雷开发小记(3)web版扫雷开发小记(4) ...

  • 小记

    小记

  • 参观中药房

    今天是孩子第一次参加安广小记者的活动,早早的起床,穿上小记者的马甲,带上小记者帽子,还有小记者的专用笔和...

  • 参观中药房

    今天是孩子第一次参加安广小记者的活动,早早的起床,穿上小记者的马甲,带上小记者帽子,还有小记者的专用笔和...

  • Web扫雷开发小记(1)

    目录Web扫雷开发小记(2)Web扫雷开发小记(3)Web扫雷开发小记(4) 刚好今天做阿里前端笔试问到扫雷了,那...

  • web版扫雷开发小记(4)

    目录:Web扫雷开发小记(1)Web扫雷开发小记(2)Web扫雷开发小记(3) 其实在完成上篇的功能之后,一个扫雷...

  • #悦读养成计划Day15#

    见 小记

  • 2017-07-15

    东海小记

  • 《散文小记》

    《散文小记》 ...

网友评论

      本文标题:setValue-forKey小记

      本文链接:https://www.haomeiwen.com/subject/xsnduxtx.html