實現(xiàn)思路
把json字符串轉(zhuǎn)為NSDictionary饭入。
NSData *jsonData = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
jsonDic = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:nil];
通過runtime的方法嵌器,來獲取類的所有屬性值,并放入一個數(shù)組谐丢。
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的屬性賦對應(yīng)的值。
Ivar ivar = class_getInstanceVariable(class, [[NSString stringWithFormat:@"_%@",prop] UTF8String]);
object_setIvar(object, ivar, arr);
利用一個遞歸乾忱,來解決嵌套json字符串的問題讥珍。
model中,實現(xiàn)propertyNameDic這個方法窄瘟,可以達到key映射的功能衷佃。key為json字符串的key,value為model的屬性蹄葱。
@implementation JsonModel
+ (NSDictionary *)propertyNameDic {
return @{@"Content":@"Con",@"Data":@"Da"};
}
@end
下面是具體的實現(xiàn)代碼氏义。
(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是否和屬性能對應(yīng)上
- (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;
}