一览表
- 一、Model中使用NSNumber代替基本数据类型int、NSInteger、bool、float等
- 问题场景一:数据为null
- 问题场景二:数据过长(时间戳)
- 二、单层Model 与 JSON 相互转换
- 问题一:Model 属性名和 JSON 中的 Key 不相同
- 问题二:数据校验与自定义转换
- 三、容器类型 In Model
- 四、黑白名单使用
- Demo
一、Model中使用NSNumber代替基本数据类型int、NSInteger、bool、float等
NSNumber类型有点类似id类型,NSNumber不用关心是什么具体的数据类型不管是int、float、double,使用时候才确定。
// 将基本数据类型保存为NSNumber 对象类型
NSNumber *intNum = [NSNumber numberWithInt:10];
NSNumber *floatNum = [NSNumber numberWithFloat:10.32];
NSNumber *doubleNum = [NSNumber numberWithDouble:345.567890];
NSNumber *boolNum = [NSNumber numberWithBool:YES];
// 将NSNumber 对象类型还原成基本数据类型
int value1 = [intNum intValue];
float value2 = [floatNum floatValue];
double value3 = [doubleNum doubleValue];
BOOL value4 = [boolNum boolValue];
// 简介写法
NSNumber *num = @1;
NSNumber *num1 = @3.14;
NSNumber *num2 = @343.33434344;
NSNumber *num3 = @YES;
问题场景一:数据为null
如果数据为null
,使用NSInteger
,并且 [p setValuesForKeysWithDictionary:dic];
就会出错,理由:could not set nil as the value for the key age.
;相反使用NSNumber就不会,因为它是一个对象;
// 1.JSON
{"age":null}
// 2.Model
@property (nonatomic, assign) NSInteger age;
// 3.原生方法转换
Dictionary *result = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];
User *user = [[User alloc] init];
[user setValuesForKeysWithDictionary:result];
// 3.1.结果
Crash 崩溃
问题场景二:数据过长(时间戳)
// 1.JSON
{"timestamp" : 1558681681123}
// 2.Model
@property (nonatomic, assign) int timestamp;
// 3.YYModel转换
User *user = [User yy_modelWithDictionary:json];
NSLog(@"user.timestamp = %d",user.timestamp);
// 4.输出
timestamp = "-391447325";
二、单层Model 与 JSON 相互转换
// 1.JSON
{
"id":123,
"name":"Harry",
"age":"22",
"created":"1965-07-31T00:00:00+0000",
"timestamp" : 1558690635,
"isstu":"yesaa"
}
// 2.Model
@property (nonatomic, copy) NSNumber *uid;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSNumber *age;
@property (nonatomic, copy) NSDate *created; // 自定义属性
@property (nonatomic, copy) NSString *created_String; // 自定义属性
@property (nonatomic, copy) NSNumber *timestamp;
@property (nonatomic, copy) NSNumber *isstu;
// 3.Convert json to model:
User *user = [User yy_modelWithDictionary:json];
// 3.1.输出
uid = 123
name = Harry
age = 22
createT = Fri May 24 17:38:08 2019
createT_String = 2019-05-24 17:38:08
timestamp = 1558690635
isstu = 0
// 4.Convert model to json:
NSDictionary *jsonConvert = [user yy_modelToJSONObject];
// 4.1.输出
{
age = 22;
created = "2019-05-24T17:38:08+0800";
"created_String" = "2019-05-24 17:38:08";
id = 123;
isstu = 0;
name = Harry;
timestamp = 1558690635;
}
问题一:Model 属性名和 JSON 中的 Key 不相同
JSON中的 id
与 Model中的 uid
/* 返回一个 Dict,将 Model 属性名对映射到 JSON 的 Key。
*
* 1. 该方法是 `字典里的属性Key` 和 `要转化为模型里的属性名` 不一样 而重写的
* 前:模型的属性 后:字典里的属性
*/
+ (NSDictionary *)modelCustomPropertyMapper {
return @{@"uid" : @"id"};
// 映射可以设定多个映射字段
// return @{@"uid":@[@"id",@"uid",@"ID"]};
}
问题二:数据校验与自定义转换
JSON中的timestamp
与 Model中的created
&created_String
/* 当 JSON转为 Model完成后,该方法会被调用。
*
* 1. 你可以在这里对数据进行校验,如果校验不通过,可以返回 NO,则该 Model会被忽略。
* 2. 你也可以在这里做一些自动转换不能完成的工作。
*/
- (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dic {
NSNumber *timestamp = dic[@"timestamp"];
if (![timestamp isKindOfClass:[NSNumber class]]) return NO;
// created
_created = [NSDate dateWithTimeIntervalSince1970:timestamp.floatValue];
// created_String
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
_created_String = [dateFormatter stringFromDate:_created];
return YES;
}
三、容器类型 In Model
// 1.JSON
{
"name":"Harry",
"age":"22",
"languages":["汉语","英语","法语"],
"friendinfo":{
"name":"J.K.Rowing.",
"age":55
},
"students":[
{
"name":"stu001",
"sex":"男"
},
{
"name":"stu002",
"sex":"男"
},
{
"name":"stu003",
"sex":"女"
}
]
}
// 2.Model
@interface StudentModel : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *sex;
@end
@interface TeacherModel : NSObject
@property (copy, nonatomic) NSString *name;
@property (assign, nonatomic) int age;
@property (strong, nonatomic) NSArray *languages;
@property (strong, nonatomic) NSDictionary *friendinfo;
// 自定义容器类中的数据类型
@property (nonatomic, strong) NSArray * students;
@end
@implementation TeacherModel
// 返回容器类中的所需要存放的数据类型 (以 Class 或 Class Name 的形式)。
+ (NSDictionary *)modelContainerPropertyGenericClass {
// 方式一:
return @{@"students" : [StudentModel class]};
// 方式二:
return @{@"students" : StudentModel.class};
// 方式三:
return @{@"students" : @"StudentModel"};
}
@end
// 3.Convert json to model:
TeacherModel *teacher = [TeacherModel yy_modelWithDictionary:json];
// 4.Convert model to json:
NSDictionary *jsonDict = [teacher yy_modelToJSONObject];
四、黑白名单使用
// 1.JSON
{
"uid":12,
"name":"Harry",
"sex":"男"
}
// 2.Model
@interface BlackAndWhiteList : NSObject
@property (nonatomic, assign) NSInteger uid;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *sex;
@end
@implementation BlackAndWhiteList
// 如果实现了该方法,则处理过程中不会处理该列表外的属性。
+ (NSArray *)modelPropertyWhitelist {
return @[@"uid",@"name"];
}
// 如果实现了该方法,则处理过程中会忽略该列表内的所有属性
+ (NSArray *)modelPropertyBlacklist {
return @[@"uid"];
}
@end
// 3.Convert json to model:
BlackAndWhiteList *blacklistAndWhitelist = [BlackAndWhiteList yy_modelWithDictionary:json];
// 3.1.输出
会根据黑白名单进行属性的过滤。
// 4.Convert model to json:
NSDictionary *jsonDict = [blacklistAndWhitelist yy_modelToJSONObject];
// 4.1.输出
{
name = Harry;
uid = 12;
}
参考
- 一篇文章全吃透—史上最全YYModel的使用详解