核心代码
+ (void)propertyCodeWithDictinoray:(NSDictionary *)dic{
NSMutableString *muStr = [NSMutableString string];
[dic enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
NSString *str;
NSLog(@"%@",[obj class]);
if ([obj isKindOfClass:NSClassFromString(@"__NSCFString")] || [obj isKindOfClass:NSClassFromString(@"NSTaggedPointerString")] || [obj isKindOfClass:NSClassFromString(@"__NSCFConstantString")]) {
str = [NSString stringWithFormat:@"@property (nonatomic, copy) NSString *%@;",key];
}
if ([obj isKindOfClass:NSClassFromString(@"__NSCFNumber")]) {
str = [NSString stringWithFormat:@"@property (nonatomic, assign) int %@;",key];
}
if ([obj isKindOfClass:NSClassFromString(@"__NSCFArray")] || [obj isKindOfClass:NSClassFromString(@"__NSArrayI")]) {
str = [NSString stringWithFormat:@"@property (nonatomic, copy) NSArray *%@;",key];
}
if ([obj isKindOfClass:NSClassFromString(@"__NSCFDictionary")]) {
str = [NSString stringWithFormat:@"@property (nonatomic, copy) NSDictionary *%@;",key];
}
if ([obj isKindOfClass:NSClassFromString(@"__NSCFBoolean")]) {
str = [NSString stringWithFormat:@"@property (nonatomic, assign) BOOL %@;",key];
}
[muStr appendFormat:@"\n%@\n",str];
}];
NSLog(@"%@",muStr);
}
判断字典中,返回值的属性,并根据相应的属性,定义
核心代码
使用方法
HomeModel = [HomeModel mj_objectWithKeyValues:successModel.data];
根据传入的数据转为模型(传入的数据可以为字典类型或者json字符串类型)
+ (instancetype)mj_objectWithKeyValues:(id)keyValues
{
return [self mj_objectWithKeyValues:keyValues context:nil];
}
mj_objectWIthKeyValues中的处理方法
+ (instancetype)mj_objectWithKeyValues:(id)keyValues context:(NSManagedObjectContext *)context
{
keyValues = [keyValues mj_JSONObject];
MJExtensionAssertError([keyValues isKindOfClass:[NSDictionary class]], nil, [self class], @"keyValues参数不是一个字典");
if ([self isSubclassOfClass:[NSManagedObject class]] && context) {
NSString *entityName = [NSStringFromClass(self) componentsSeparatedByString:@"."].lastObject;
return [[NSEntityDescription insertNewObjectForEntityForName:entityName inManagedObjectContext:context] mj_setKeyValues:keyValues context:context];
}
return [[[self alloc] init] mj_setKeyValues:keyValues];
}
其中mj_JSONObject对传入的数据进行处理
- (id)mj_JSONObject
{
if ([self isKindOfClass:[NSString class]]) {
return [NSJSONSerialization JSONObjectWithData:[((NSString *)self) dataUsingEncoding:NSUTF8StringEncoding] options:kNilOptions error:nil];
} else if ([self isKindOfClass:[NSData class]]) {
return [NSJSONSerialization JSONObjectWithData:(NSData *)self options:kNilOptions error:nil];
}
return self.mj_keyValues;
}
传入的数据为json或者data数据类型的时候,把数据转化为NSDictionary格式
核心解析方法
- (instancetype)mj_setKeyValues:(id)keyValues context:(NSManagedObjectContext *)context
{
keyValues = [keyValues mj_JSONObject];
MJExtensionAssertError([keyValues isKindOfClass:[NSDictionary class]], self, [self class], @"keyValues参数不是一个字典");
Class clazz = [self class];
NSArray *allowedPropertyNames = [clazz mj_totalAllowedPropertyNames];
NSArray *ignoredPropertyNames = [clazz mj_totalIgnoredPropertyNames];
[clazz mj_enumerateProperties:^(MJProperty *property, BOOL *stop) {
@try {
if (allowedPropertyNames.count && ![allowedPropertyNames containsObject:property.name]) return;
if ([ignoredPropertyNames containsObject:property.name]) return;
id value;
NSArray *propertyKeyses = [property propertyKeysForClass:clazz];
for (NSArray *propertyKeys in propertyKeyses) {
value = keyValues;
for (MJPropertyKey *propertyKey in propertyKeys) {
value = [propertyKey valueInObject:value];
}
if (value) break;
}
id newValue = [clazz mj_getNewValueFromObject:self oldValue:value property:property];
if (newValue != value) {
[property setValue:newValue forObject:self];
return;
}
if (!value || value == [NSNull null]) return;
MJPropertyType *type = property.type;
Class propertyClass = type.typeClass;
Class objectClass = [property objectClassInArrayForClass:[self class]];
if (propertyClass == [NSMutableArray class] && [value isKindOfClass:[NSArray class]]) {
value = [NSMutableArray arrayWithArray:value];
} else if (propertyClass == [NSMutableDictionary class] && [value isKindOfClass:[NSDictionary class]]) {
value = [NSMutableDictionary dictionaryWithDictionary:value];
} else if (propertyClass == [NSMutableString class] && [value isKindOfClass:[NSString class]]) {
value = [NSMutableString stringWithString:value];
} else if (propertyClass == [NSMutableData class] && [value isKindOfClass:[NSData class]]) {
value = [NSMutableData dataWithData:value];
}
if (!type.isFromFoundation && propertyClass) {
value = [propertyClass mj_objectWithKeyValues:value context:context];
} else if (objectClass) {
if (objectClass == [NSURL class] && [value isKindOfClass:[NSArray class]]) {
NSMutableArray *urlArray = [NSMutableArray array];
for (NSString *string in value) {
if (![string isKindOfClass:[NSString class]]) continue;
[urlArray addObject:string.mj_url];
}
value = urlArray;
} else {
value = [objectClass mj_objectArrayWithKeyValuesArray:value context:context];
}
} else {
if (propertyClass == [NSString class]) {
if ([value isKindOfClass:[NSNumber class]]) {
value = [value description];
} else if ([value isKindOfClass:[NSURL class]]) {
value = [value absoluteString];
}
} else if ([value isKindOfClass:[NSString class]]) {
if (propertyClass == [NSURL class]) {
value = [value mj_url];
} else if (type.isNumberType) {
NSString *oldValue = value;
if (type.typeClass == [NSDecimalNumber class]) {
value = [NSDecimalNumber decimalNumberWithString:oldValue];
} else {
value = [numberFormatter_ numberFromString:oldValue];
}
if (type.isBoolType) {
NSString *lower = [oldValue lowercaseString];
if ([lower isEqualToString:@"yes"] || [lower isEqualToString:@"true"]) {
value = @YES;
} else if ([lower isEqualToString:@"no"] || [lower isEqualToString:@"false"]) {
value = @NO;
}
}
}
}
if (propertyClass && ![value isKindOfClass:propertyClass]) {
value = nil;
}
}
[property setValue:value forObject:self];
} @catch (NSException *exception) {
MJExtensionBuildError([self class], exception.reason);
MJExtensionLog(@"%@", exception);
}
}];
if ([self respondsToSelector:@selector(mj_keyValuesDidFinishConvertingToObject)]) {
[self mj_keyValuesDidFinishConvertingToObject];
}
return self;
}
分析
mj_setupAllowedPropertyNames:+mj_totalAllowedPropertyNames,白名单/归档配置mj_setupAllowedCodingPropertyNames:+mj_totalAllowedCodingPropertyNames
mj_setupIgnoredPropertyNames:+mj_totalIgnoredPropertyNames,黑名单/归档配置mj_setupIgnoredCodingPropertyNames:+mj_totalIgnoredCodingPropertyNames
根据黑白名单进行数据监测,并对数据进行处理
此时需要在model.m中进行设置如下方法
例如:
+(NSDictionary *)mj_replacedKeyFromPropertyName
{
// 实现这个方法的目的:告诉MJExtension框架模型中的属性名对应着字典的哪个key
return @{
@"ID" : @"id",
}
或者在初始化model时添加
[Model mj_setupReplacedKeyFromPropertyName:^NSDictionary *{
return @{@"ID":@"id"};
}];
即此方法mj_objectWithKeyValues可以一次性转化,字典内的字典为模型
mj_objectArrayWithKeyValuesArray
此方法可以在获取数据时,直接转为为model数组
例如:
NSArray *userArray = [User mj_objectArrayWithKeyValuesArray:dictArray];
使用mj_keyValues属性
例如:
NSDictionary *mdoelDic = model.mj_keyValues;
使用mj_keyValuesArrayWithObjectArray方法
例如:
NSArray *dictArray = [User mj_keyValuesArrayWithObjectArray:userArray];