使用mj解析多层级json数据笔记

一、数据获取
1.这里是从服务端接口获取的GMTAfterSaleModel的数据源

[ { "status": "403", "id": 55, "moId": "20210317194857255725536", "orderEntityList": [ { "goodsCount": 1, "id": "20210317194857255725536", "shippingNo": "123", "privCouponPrice": 3.9900000000000002, "shippingName": "新鹏快递", "province": "上海市", "goodsId": "98631affe4da53145fb41e40997e9f22", "goodsOnSale": true, "shippingId": "001e5b2ee3887630aa601807979fb02c", "orderGoodsEntityList": [ { "number": 1, "orderId": "20210317194857255725536", "goodsName": "南国食品壹分", "id": "3c592c55675d530caba7a8a7bc92d5ae", "goodsId": "98631affe4da53145fb41e40997e9f22", "retailPrice": 4, "skuText": "规格:默认 ", "skuId": "0570c97793da97bbdcd70e4e7f5870ca", "listPicUrl": "http://qiniu.hnjzt.ltd/20210202/a10715de398e4a33b9329e7c982eab82.png", "goodsSn": "123" } ], "shippingStatus": 3, "payStatus": 3, "payType": 0, "orderStatus": 301, "actualPrice": 0.01, "refundTime": "2021-03-17 20:03:06", "orderPrice": 4, "goodsName": "南国食品壹分", }, ]

2.这里是从服务端接口获取到的GMTOurOrderModel的数据源
[{ "goodsCount": 1, "id": "20210323110220436781900", "goodsId": "98631affe4da53145fb41e40997e9f22", "goodsOnSale": true, "orderTypeText": "商城订单", "orderGoodsEntityList": [ { "id": "f0cf192112d2fae3a8dafbf7a815b705", "couponId": null, "payZhi": 0, "shippingFee": 0, "postscript": null, "privCouponPrice": 0, "goodsSn": "123", "retailPrice": 4, "skuId": "0570c97793da97bbdcd70e4e7f5870ca", "orderId": "20210323110220436781900", "goodsName": "南国食品壹分", "number": 1, "skuText": "规格:默认 ", "listPicUrl": "http://qiniu.hnjzt.ltd/20210202/a10715de398e4a33b9329e7c982eab82.png", "goodsId": "98631affe4da53145fb41e40997e9f22", } ], "shippingStatus": 1, "payStatus": 2, "orderStatus": 0, "actualPrice": 0.01, "refundTime": null, "orderPrice": 4, },]

二、数据对比
数据上来讲,字段基本上没有变化,层级有所不同,取值上来讲也是同一种列表需要,因此最基本的实现功能的办法是写三个model,Demo中的 GMTOurOrderModel 、GMTAfterSaleModel 和OrderGoodsEntityList。
具体实现方法这里是常规操作,这里不赘述,下面直接说下优化方案。
将GMTAfterSaleModel数据源中的orderEntityList中的数据提出到外层,(这里是数组,服务端只会返回一个值,没必要放里层,可以提出到外层),期望将GMTAfterSaleModel的数据源变成如下的方案来进行解析。
[ { "status": "403", "id": 55, "moId": "20210317194857255725536", "goodsCount": 1, "id": "20210317194857255725536", "shippingNo": "123", "privCouponPrice": 3.9900000000000002, "shippingName": "新鹏快递", "province": "上海市", "goodsId": "98631affe4da53145fb41e40997e9f22", "goodsOnSale": true, "shippingId": "001e5b2ee3887630aa601807979fb02c", "orderGoodsEntityList": [ { "number": 1, "orderId": "20210317194857255725536", "goodsName": "南国食品壹分", "id": "3c592c55675d530caba7a8a7bc92d5ae", "goodsId": "98631affe4da53145fb41e40997e9f22", "retailPrice": 4, "skuText": "规格:默认 ", "skuId": "0570c97793da97bbdcd70e4e7f5870ca", "listPicUrl": "http://qiniu.hnjzt.ltd/20210202/a10715de398e4a33b9329e7c982eab82.png", "goodsSn": "123" } "shippingStatus": 3, "payStatus": 3, "payType": 0, "orderStatus": 301, "actualPrice": 0.01, "refundTime": "2021-03-17 20:03:06", "orderPrice": 4, "goodsName": "南国食品壹分", }, ]

这样来看既方便解析,又方便取值。
步骤1:需要写的内容是,需要将给GMTAfterSaleModel.h文件中添加goodsCount、shippingNo等属性。
步骤2:在GMTAfterSaleModel.m文件中需要实现的方法是
+(instancetype)mj_objectWithKeyValues:(id)keyValues context:(NSManagedObjectContext *)context { NSDictionary * dic = [[NSArray arrayWithArray:keyValues[@"orderEntityList"]] firstObject]; GMTAfterSaleModel * model = [[[GMTAfterSaleModel alloc] mj_setKeyValues:dic] mj_setKeyValues:keyValues]; return model; }

步骤3.里层包含一个orderGoodsEntityList的处理方法
+(NSDictionary *)mj_objectClassInArray { return @{@"orderGoodsEntityList":[OrderGoodsEntityList class]}; }

这样就可以将GMTAfterSaleModel完整赋值。
三、设置父类
接下来可以进一步优化,将GMTAfterSaleModel设置为GMTOurOrderModel的子类进行优化,方便取值。还可以删掉GMTAfterSaleModel。
直接上代码
+(NSDictionary *)mj_objectClassInArray { return @{@"orderGoodsEntityList":[OrderGoodsEntityList class]}; }+(instancetype)mj_objectWithKeyValues:(id)keyValues context:(NSManagedObjectContext *)context { if ([keyValues objectForKey:@"orderEntityList"]) { NSDictionary * dic = [[NSArray arrayWithArray:keyValues[@"orderEntityList"]] firstObject]; GMTOurOrderModel * model = [[[GMTOurOrderModel alloc] mj_setKeyValues:dic] mj_setKeyValues:keyValues]; return model; }else { return[super mj_objectWithKeyValues:keyValues context:context]; } }

else语句处理父类的解析,if语句处理子类的解析,没冲突。
四、整理业务需求
【使用mj解析多层级json数据笔记】将显示cell所需要的业务数据提前封装,在cell的setModel方法里直接取值
/* 业务数据 */@property(nonatomic,assign)CGRect contentRect; @property(nonatomic,strong)NSArray * btnsArr; @property(nonatomic,strong)NSString * title;

实现见demo
demo:
https://gitee.com/xgkp/deal.git

    推荐阅读