目录
1. JSONModel
2. MJExtension(建议)
3. YYModel
前言
原本使用的一直是JSONModel,因为后台的一次失误(数组类型的字段偶尔返回成字符串),造成数据解析不出来。
而且JSONModel侵入性较高(1.需要继承JSONModel;2.处理元素类型为类类型的数组属性时繁琐)。
因此,果断放弃使用JSONModel,改用MJExtension。
1. JSONModel
- 使用
第一步 :cocoaPods引入
# JSONModel
pod 'JSONModel'
第二步:存入pch
#import <JSONModel/JSONModel.h>
第三步:自定义模型
// 每一个模型,继承JSONModel
YTPersonModel : JSONModel
第四步:转换
字典转模型
// 方式一
PersonModel *personM=[[PersonModel alloc] initWithDictionary:dic error:nil]
// 方式二
_guideArr=[YTPublishDZModel arrayOfModelsFromDictionaries:gjArr error:nil];
// 模型转字典
NSDictionary* dict = [personM toDictionary];
// 模型转字符串
NSString* string = [personM toJSONString];
- 注意事项
- 属性可选(有不需要和后台字段映射的属性)
// 方式一:指定属性可选
@property (strong, nonatomic) NSString<Optional>* name;
// 方式二:全部属性可选(推荐)
+(BOOL)propertyIsOptional:(NSString *)propertyName{
return true;
}
// 方式三:指定属性忽略
@property (strong, nonatomic) NSString<Ignore>* customProperty;
2.当属性名和后台字段不一致时 (自定义属性:后台属性)
+(JSONKeyMapper *)keyMapper{
return [[JSONKeyMapper alloc]initWithModelToJSONDictionary:@{
@"themeId":@"id",
@"Description":@"description"
}];
}
// 如果只是将下划线转为驼峰,则使用
+(JSONKeyMapper *)keyMapper{
// 将后台返回的_a 改为 A (将驼峰模式改为下划线模式)
return [JSONKeyMapper mapperForSnakeCase];
}
- 当属性为类类型属性,不需做额外处理。
- 当属性是数组,元素类型为类类型
数组(类类型) 属性
// 方式一
@protocol NewsDetailItem
@end
@property(nonatomic, strong) NSArray<NewsDetailItem> *ewsDetailItemArray;
// 方式二
// 当使用arrayOfModelsFromDictionaries转换时,会调用此方法
-(instancetype)initWithDictionary:(NSDictionary *)dict error:(NSError *__autoreleasing *)err{
self=[super initWithDictionary:dict error:err];
if(self){
_currentRoundM=[[ZYDDataScheduleItemModel arrayOfModelsFromDictionaries:@[dict[@"current_round"]] error:nil]firstObject];
//
NSArray *dayNumArr=dict[@"tripDayList"];
_tripDayList=[YTDayModel arrayOfModelsFromDictionaries:dayNumArr error:nil];
//
if(dict[@"readyTime"]){
_readyTime=[dict[@"readyTime"] intValue];
}else if(dict[@"redayTime"]){
_readyTime=[dict[@"redayTime"] intValue];
}
}
return self;
}
2. MJExtension
第一步 :cocoaPods引入
pod 'MJExtension'
第二步:自定义模型(不需要继承)
BaseModel.h
#import <Foundation/Foundation.h>
@interface BaseModel : NSObject
@property (nonatomic, copy) NSString *ID;
@end
BaseModel.m
#import "BaseModel.h"
@implementation BaseModel
@end
第三步:转换
// 字典转模型
BaseModel *model = [BaseModel objectWithKeyValues:dict];
// 字典数组转模型数组
NSArray *selecteds = [BaseModel mj_objectArrayWithKeyValuesArray:dic[@"response"][@"selected"]
// 模型转字典
NSDictionary *personDict = personModel.keyValues;
// 模型数组转字典数组
NSArray *dictArray = [PersonModel keyValuesArrayWithObjectArray:personArray];
- 注意事项
1、当属性为类类型属性,不需做额外处理。
2、当属性是数组,元素类型为类类型。
+ (NSDictionary *)objectClassInArray{
return @{
@"personArray" : @"PersonModel",
@"teamArray" : @"TeamModel",
};
}
/*
另外2种方式(不推荐,要引入头文件):
+ (NSDictionary *)objectClassInArray{
return @{
@"personArray" : [PersonModel class],
@"teamArray" : [TeamModel class],
};
}
+ (Class)objectClassInArray:(NSString *)propertyName{
if ([propertyName isEqualToString:@"personArray"]) {
return [PersonModel class];
} else if ([propertyName isEqualToString:@"teamArray"]) {
return [TeamModel class];
}
return nil;
}
*/
3、当属性名和后台字段不一致时
+ (NSDictionary *)replacedKeyFromPropertyName{
NSDictionary *dict = @{
@"ID": @[@"id",@"houseId"] ,
@"descriptions":@"description"
};
return dict;
}
3. YYModel
// 字典转模型
/**
类型不匹配时
`NSString` or `NSNumber` -> c语言类型 number, such as BOOL, int, long, float, NSUInteger...
`NSString` -> NSDate, parsed with format "yyyy-MM-dd'T'HH:mm:ssZ", "yyyy-MM-dd HH:mm:ss" or "yyyy-MM-dd".
`NSString` -> NSURL.
`NSValue` -> struct or union, such as CGRect, CGSize, ...
`NSString` -> SEL, Class.
*/
+ (nullable instancetype)modelWithDictionary:(NSDictionary *)dictionary;
// json转模型。json: `NSDictionary`, `NSString` or `NSData
+ (nullable instancetype)modelWithJSON:(id)json;
// 模型转NSObject
- (nullable id)modelToJSONObject;
// 模型转NSData
- (nullable NSData *)modelToJSONData;
// 模型转json字符串
- (nullable NSString *)modelToJSONString;
// 模型深拷贝
- (nullable id)modelCopy;
// 判断模型是否相等
- (BOOL)modelIsEqual:(id)model;
// 当属性名和后端字段不一致时使用
+ (nullable NSDictionary<NSString *, id> *)modelCustomPropertyMapper;
// 元素为类类型的数组属性
+ (nullable NSDictionary<NSString *, id> *)modelContainerPropertyGenericClass;
// 属性黑名单,忽略
+ (nullable NSArray<NSString *> *)modelPropertyBlacklist;
// 属性白名单,仅处理
+ (nullable NSArray<NSString *> *)modelPropertyWhitelist;
// JSON 转为 Model 完成后调用,返回false该model会被忽略
- (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dic;
// Model 转为 JSON 完成后调用,返回false该model会被忽略
- (BOOL)modelCustomTransformToDictionary:(NSMutableDictionary *)dic
- 使用
第一步 :cocoaPods引入
pod 'YYKit'
第二步:自定义模型(不需要继承)
BaseModel.h
#import <Foundation/Foundation.h>
@interface BaseModel : NSObject
@property (nonatomic, copy) NSString *ID;
@end
BaseModel.m
#import "BaseModel.h"
@implementation BaseModel
@end
第三步:转换
// 字典转模型
FQUserTagModel *tagM=[FQUserTagModel modelWithDictionary:dic];
- 注意事项
- 当属性名和后台字段不一致时
@property (nonatomic,copy) NSString *tagId; // 后端返回id
+ (nullable NSDictionary<NSString *, id> *)modelCustomPropertyMapper{
return @{
@"tagId":@"id",
// @"tagId":@[@"id",@"uid",@"ID"]
};
}
- 当属性是数组,元素类型为类类型
@property (nonatomic,copy) NSArray *childrenArr;
+ (NSDictionary *)modelContainerPropertyGenericClass {
return @{
@"childrenArr" : @"FQUserTagModel",
};
}
- 取sexDic中的sex @{@"sexDic":@{@"sex":@"boy"}}
@property (nonatomic,copy) NSString *sex;
+ (NSDictionary *)modelContainerPropertyGenericClass {
return @{
@"sex":@"sexDic.sex",
};
}
- 黑白名单
// 以下两个方法不同时使用
// 忽略该列表内的所有属性
+ (NSArray *)modelPropertyBlacklist {
return @[@"sex", @"languages"];
}
// 仅处理该列表内的属性。
+ (NSArray *)modelPropertyWhitelist {
return @[@"eats"];
}
- 完成转换后的调用方法
// 当 JSON 转为 Model 完成后调用。
- (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dic {
// ...自定义处理
return YES;
}
// 当 Model 转为 JSON 完成后调用。
- (BOOL)modelCustomTransformToDictionary:(NSMutableDictionary *)dic {
// ...自定义处理
return YES;
}
- 深拷贝
FQUserTagModel *tagTmpM=[tagM modelCopy];
- NSCoding
<NSCoding>
- (void)encodeWithCoder:(NSCoder *)aCoder {
[self modelEncodeWithCoder:aCoder];
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
return [self modelInitWithCoder:aDecoder];
}
- modelIsEqual
- (BOOL)isEqual:(id)object {
return [self modelIsEqual:object];
}