实现思路
把json字符串转为NSDictionary。
NSData *jsonData = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
jsonDic = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil];
通过runtime的方法,来获取类的所有属性值,并放入一个数组。
u_int count;
objc_property_t *properties = class_copyPropertyList(class, &count);
NSMutableArray *propertiesArray = [NSMutableArray arrayWithCapacity:count];
for (int i = 0; i<count; i++)
{
const char* propertyName =property_getName(properties[i]);
[propertiesArray addObject: [NSString stringWithUTF8String: propertyName]];
}
free(properties);
依然是通过runtime的方法,给model的属性赋对应的值。
Ivar ivar = class_getInstanceVariable(class, [[NSString stringWithFormat:@"_%@",prop] UTF8String]);
object_setIvar(object, ivar, arr);
利用一个递归,来解决嵌套json字符串的问题。
model中,实现propertyNameDic这个方法,可以达到key映射的功能。key为json字符串的key,value为model的属性。
@implementation JsonModel
+ (NSDictionary *)propertyNameDic {
return @{@"Content":@"Con",@"Data":@"Da"};
}
@end
下面是具体的实现代码。
(NSDictionary *)propertyNameDic {
return nil;
}
+ (id)jsonToModel:(NSString *)jsonStr {
NSDictionary *jsonDic;
NSData *jsonData = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
jsonDic = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil];
NSData *data = [NSJSONSerialization dataWithJSONObject:jsonDic options:NSJSONWritingPrettyPrinted error:nil];
NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
}
id obj = [self finishToModel:[self class] jsonDic:jsonDic];
return obj;
}
- (id)finishToModel:(Class)class jsonDic:(NSDictionary *)jsonDic{
id object = [[class alloc] init];
NSArray *propertiesArray = [self getAllProperties:class];
for (NSString *key in jsonDic) {
for (NSString *prop in propertiesArray) {
if ([self propertyIsEqual:prop toKey:key withClass:class]) {
if ([jsonDic[key] isKindOfClass:[NSDictionary class]]) {
NSDictionary *subDic = jsonDic[key];
id o = [self finishToModel:[NSClassFromString(key) class] jsonDic:subDic];
Ivar ivar = class_getInstanceVariable(class, [[NSString stringWithFormat:@"_%@",prop] UTF8String]);
object_setIvar(object, ivar, o);
break;
}else if ([jsonDic[key] isKindOfClass:[NSArray class]]) {
NSArray *jsonArr = jsonDic[key];
NSMutableArray *arr = [[NSMutableArray alloc] init];
[jsonArr enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
id o = [self finishToModel:[NSClassFromString(key) class] jsonDic:obj];
[arr addObject:o];
}];
Ivar ivar = class_getInstanceVariable(class, [[NSString stringWithFormat:@"_%@",prop] UTF8String]);
object_setIvar(object, ivar, arr);
break;
}else {
Ivar ivar = class_getInstanceVariable(class, [[NSString stringWithFormat:@"_%@",prop] UTF8String]);
object_setIvar(object, ivar, jsonDic[key]);
break;
}
}
}
}
return object;
}
//比较传进来的key是否和属性能对应上
- (BOOL)propertyIsEqual:(NSString *)prop toKey:(NSString *)key withClass:(Class)class{
if ([prop isEqualToString:key]) {
return YES;
}
NSDictionary *propertyNameDic = nil;
if ([class respondsToSelector:@selector(propertyNameDic)]) {
propertyNameDic = [class propertyNameDic];
}
if ([propertyNameDic[key] isEqualToString:prop]) {
return YES;
}else {
return NO;
}
}
//获取对象的所有属性,不包括属性值
- (NSArray *)getAllProperties:(Class)class
{
u_int count;
objc_property_t *properties = class_copyPropertyList(class, &count);
NSMutableArray *propertiesArray = [NSMutableArray arrayWithCapacity:count];
for (int i = 0; i<count; i++)
{
const char* propertyName =property_getName(properties[i]);
[propertiesArray addObject: [NSString stringWithUTF8String: propertyName]];
}
free(properties);
return propertiesArray;
}
//获取对象的所有属性 以及属性值
- (NSDictionary *)properties_aps
{
NSMutableDictionary *props = [NSMutableDictionary dictionary];
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList([self class], &outCount);
for (i = 0; i<outCount; i++)
{
objc_property_t property = properties[i];
const char* char_f =property_getName(property);
NSString *propertyName = [NSString stringWithUTF8String:char_f];
id propertyValue = [self valueForKey:(NSString *)propertyName];
if (propertyValue) [props setObject:propertyValue forKey:propertyName];
}
free(properties);
return props;
}