iOS开发中,经常会用到字典转模型,咱们平常常用的是MJExstend框架,该框架功能完善,但是在咱们用的时候基本上只是在数据解析的时候会用到json字典转模型,仅此一个功能,你们庞大的一套框架,是不是有些浪费啦,所以咱们自己写一个小的分类,运用<objc/runtime.h>一点点知识点就可以搞定,下面直接上代码:该分类有三个功能:(1)字典 转 模型;(2)模型 转字符串;(3)模型 转 字典。
#import <Foundation/Foundation.h>
@interface NSObject (ZJExtend)
+(instancetype)modelWithJson:(NSDictionary *)json;
-(NSDictionary *)objClassInPropertyName;
-(NSString *)toString;
-(NSDictionary*)toDictionary;
@end
#import "NSObject+ZJExtend.h"
#import <objc/runtime.h>
@implementation NSObject (ZJExtend)
/** 属性名称里内存放的类型
* @{@"propertyName":@"Class"} 即属性名称:存放类型
*/
-(NSDictionary *)objClassInPropertyName{
return [NSDictionary dictionary];
}
+(instancetype)modelWithJson:(NSDictionary *)json{
id model = [[self alloc] init];
if (model && [json isKindOfClass:[NSDictionary class]]){
// 遍历所有属性 采用KVO赋值
unsigned int count;
objc_property_t *properties = class_copyPropertyList([model class], &count);
for(int i=0;i<count;i++){
objc_property_t property = properties[i];
const char * name = property_getName(property);
NSString * propertyName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
// 取出对于的value
id value = [json objectForKey:propertyName];
if([value isKindOfClass:[NSDictionary class]]){
id tempModel = [model handleJDictionaryJson:value WithPropertyName:propertyName];
[model setValue:tempModel forKey:propertyName];
}else if([value isKindOfClass:[NSArray class]]){
NSArray * tempArray = [model handleJArrayJson:value WithPropertyName:propertyName];
[model setValue:tempArray forKey:propertyName];
}else if([value isKindOfClass:[NSString class]]){
[model setValue:value forKey:propertyName];
}else if([value isKindOfClass:[NSNumber class]]){
NSString * string = [NSString stringWithFormat:@"%@",value];
[model setValue:string forKey:propertyName];
}else{
}
}
free(properties);
}
return model;
}
-(id)handleJDictionaryJson:(NSDictionary *)json WithPropertyName:(NSString *)propertyName{
NSDictionary * tempDictionary = [self objClassInPropertyName];
for(NSString * tempKey in [tempDictionary allKeys]){
if([tempKey isEqualToString:propertyName]){
//Class tempClass = NSClassFromString([tempDictionary objectForKey:tempKey]);
Class tempClass = objc_getClass([[tempDictionary objectForKey:tempKey] UTF8String]);
id model = [[tempClass new] modelWithJson:json];
//[self setValue:model forKey:propertyName];
return model;
}
}
return nil;
}
-(NSArray*)handleJArrayJson:(NSArray *)json WithPropertyName:(NSString *)propertyName{
NSDictionary * tempDictionary = [self objClassInPropertyName];
for(NSString * tempKey in [tempDictionary allKeys]){
if([tempKey isEqualToString:propertyName]){
NSMutableArray * tempAarray = [NSMutableArray array];
for(id value in json){
if([value isKindOfClass:[NSDictionary class]]){
//Class tempClass = NSClassFromString([tempDictionary objectForKey:tempKey]);
Class tempClass = objc_getClass([[tempDictionary objectForKey:tempKey] UTF8String]);
[tempAarray addObject:[tempClass modelWithJson:value]];
}else if([value isKindOfClass:[NSArray class]]){
NSArray * subArray = [self handleJArrayJson:value WithPropertyName:propertyName];
[tempAarray addObject:subArray];
}else{
[tempAarray addObject:value];
}
}
return tempAarray;
}
}
return [NSArray array];
}
-(NSString *)toString{
NSDictionary * param = [self toDictionary];
NSError *error = nil;
//NSLog(@" = = = = %@",param);
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:param options:NSJSONWritingPrettyPrinted error:&error];
if (error) {
NSLog(@"Error occured when create json string representation, error: %@", error.localizedDescription);
}
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
return jsonString;
}
/** 将自定义的对象转换成字典对象,属性名为键,属性值为值*/
-(NSDictionary *)toDictionary{
NSMutableDictionary * param = [NSMutableDictionary new];
if(![self isKindOfClass:[NSObject class]]){
return param;
}
unsigned int count;
objc_property_t *properties = class_copyPropertyList([self class], &count);
for(int i=0;i<count;i++){
objc_property_t property = properties[i];
const char * name = property_getName(property);
NSString * propertyName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding];
id value = [self handleObjFromObj:[self valueForKey:propertyName]];;
//NSLog(@"name == %@, id == %@",propertyName,value);
[param setObject:value ? value : @"Null" forKey:propertyName];
}
free(properties);
return param;
}
-(NSDictionary*)handleStringFromDictionary:(NSDictionary*)dictionary{
[dictionary enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
obj = [self handleObjFromObj:obj];
}];
return dictionary;
}
-(NSArray*)handleStringFromArray:(NSArray*)array{
[array enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
obj = [self handleObjFromObj:obj];
}];
return array;
}
-(id)handleObjFromObj:(id)obj{
//NSLog(@"== %@",obj);
if([obj isKindOfClass:[NSDictionary class]]){
obj = [self handleStringFromDictionary:obj];
}else if([obj isKindOfClass:[NSArray class]]){
NSMutableArray * tempArray = [NSMutableArray array];
for(id subObj in (NSArray*)obj){
[tempArray addObject:[self handleObjFromObj:subObj]];
}
obj = tempArray;
}else if([obj isKindOfClass:[NSNumber class]]){
obj = [NSString stringWithFormat:@"%@",obj];
}else if([NSBundle bundleForClass:[obj class]] == [NSBundle mainBundle]){
obj = [obj toDictionary];
}
return obj;
}
@end