MJExtension使用简介

1、根据字典定义model的属性

核心代码

+ (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);
}

判断字典中,返回值的属性,并根据相应的属性,定义

2、简单json字符串、data或者字典转模型

核心代码
使用方法

 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

根据黑白名单进行数据监测,并对数据进行处理

3.模型中的属性名和字典中的属性名称不相同

此时需要在model.m中进行设置如下方法
例如:

+(NSDictionary *)mj_replacedKeyFromPropertyName
{
// 实现这个方法的目的:告诉MJExtension框架模型中的属性名对应着字典的哪个key
  return @{
           @"ID" : @"id",
}

或者在初始化model时添加

 [Model mj_setupReplacedKeyFromPropertyName:^NSDictionary *{
    return @{@"ID":@"id"};
 }];

4、字典转模型支持多重映射

即此方法mj_objectWithKeyValues可以一次性转化,字典内的字典为模型

5、字典数组转化为模型数组

mj_objectArrayWithKeyValuesArray
此方法可以在获取数据时,直接转为为model数组
例如:

  NSArray *userArray = [User mj_objectArrayWithKeyValuesArray:dictArray];

6、将一个模型转成字典

使用mj_keyValues属性
例如:

 NSDictionary *mdoelDic = model.mj_keyValues;

7、 将一个模型数组转成字典数组

使用mj_keyValuesArrayWithObjectArray方法
例如:

  NSArray *dictArray = [User mj_keyValuesArrayWithObjectArray:userArray];

你可能感兴趣的:(方法篇)