为了更方便得处理数据,使用了第三方库JsonModel。
使用JsonModel时,会根据服务器传过来的数据进行检查,如果解析时发现model中有该属性,但服务器传过来的json中没有相应数据,则会报错,使用可选属性,来避免异常。
可以用下面方法,使当前类的全部属性都为可选。
新建BaseModel来扩展JSONModel
设置所有的属性为可选
//设置所有的属性为可选
@implementation JSONModel(SafeJSONModel)
+(void)load{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
SEL org_Selector = @selector(propertyIsOptional:);
SEL dt_Selector = @selector(dt_propertyIsOptional:);
Method org_method = class_getClassMethod([self class], org_Selector);
Method dt_method = class_getClassMethod([self class], dt_Selector);
class_addMethod(self, org_Selector, method_getImplementation(dt_method), method_getTypeEncoding(dt_method));
// if (isAdd) {
// class_replaceMethod(self, dt_Selector, method_getImplementation(org_method), method_getTypeEncoding(org_method));
// }else{
method_exchangeImplementations(org_method, dt_method);
// }
});
}
+(BOOL)dt_propertyIsOptional:(NSString *)propertyName{
[self dt_propertyIsOptional:propertyName];
return YES;
}
这样之后,只要model继承了JSONModel,所有属性均为可选。
1.使用Optional协议对一些支持的类型标记可选,例如NSString ,NSNumber
其中ShopModel类型继承自JSONModel,所以支持
@interface ShopListModel : JSONModel
@property ShopModel *Device; //设备
@property NSInteger BuyNum; //购买的数量
@property NSInteger ShopingcartID; //购物车id
@property NSInteger UserID; //用户id
@property Boolean isChoice; //是否被选中购物车项
@end
2.当属性类型为不支持类型,例如Boolean时
在model的.m文件中重写父类的方法,判断属性为isChoice时,使其为可选。
@implementation ShopListModel
+ (BOOL)propertyIsOptional:(NSString *)propertyName {
if ([propertyName isEqualToString:@"isChoice"]) {
return YES;
}
return NO;
}
这样之后就可以保证后台传过来的数据都是有效的。
只要调用JsonModel 的initWithDictionary方法,就可以直接拿到model
- (void)updateInfoArray{
//清空咨询列表
self.shopArray = [[NSMutableArray alloc] init];
NSDictionary *parameters = @{@"userId":[NSString stringWithFormat:@"%ld",[UserInfoModel shareInstance].UserID]};
//访问网络
[[NetworkTool shareInstance] requireMethodType:POSTType URLString:@"DeviceManage/findAllShopingcartByUserId" parameters:parameters success:^(NSDictionary *respondDictionary) {
for (NSDictionary *dic in respondDictionary[@"result"]) {
ShopListModel *model = [[ShopListModel alloc] initWithDictionary:dic error:nil];
[self.shopArray addObject:model];
// 正常结束刷新
[self.tableView.mj_header endRefreshing];
}
[self.tableView reloadData];
} failure:^(NSError *error) {
[SVProgressHUD showfailed];
// 正常结束刷新
[self.tableView.mj_header endRefreshing];
}];
[self updateMoneySum];
}
有时, 得到的数据不是在一个层级,如下:
{
"order_id": 104,
"order_details" : [
{
"name": "Product#1",
"price": {
"usd": 12.95
}
}
]
}
其中的order_id与name就不是一个层级,但我们仍然想在一个model中得到它们的数据。 如下:
@interface OrderModel : JSONModel
@property (assign, nonatomic) int id;
@property (assign, nonatomic) float price;
@property (strong, nonatomic) NSString* productName;
@end
@implementation OrderModel
+(JSONKeyMapper*)keyMapper
{
return [[JSONKeyMapper alloc] initWithDictionary:@{
@"order_id": @"id",
@"order_details.name": @"productName",
@"order_details.price.usd": @"price" // 这里就采用了KVC的方式来取值,它赋给price属性
}];
}
@end