| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621 |
- //
- // NSObject+Json.m
- //
- //
- // Created by Alexi on 12-11-15.
- // Copyright (c) 2012年 . All rights reserved.
- //
- #import "NSObject+Json.h"
- #import <objc/runtime.h>
- #import "JSONKit.h"
- #import "IOSDeviceConfig.h"
- @implementation NSObject (Json)
- #define kServiceTag_ID @"id"
- - (void)setIdPropertyValue:(id)idkeyValue
- {
- // for the subclass to do
- }
- /*
- * 对于格式如下的方法,使用以下接口进行反序化
- * [{itemClass对应的json串},{itemClass对应的json串}...]
- * 参数说明:
- * itemClass: json列表中单个数据对要反序列化成的对像类型
- * arraydict: json列表
- */
- + (NSMutableArray *)loadItem:(Class)itemClass fromArrayDictionary:(NSArray *)arraydict
- {
- NSMutableArray *array = [[NSMutableArray alloc] init];
-
- for (NSDictionary *dic in arraydict ) {
- if (dic) {
- id value = [NSObject parse:itemClass dictionary:dic];
- [array addObject:value];
- }
- }
- return CommonReturnAutoReleased(array);
- }
- /*
- *
- */
- - (void)setValueForPropertyValue:(id)idkeyValue forKey:(NSString *)key propertyClass:(Class)cls tagretClass:(Class)targetCls
- {
- if ([idkeyValue isKindOfClass:[NSDictionary class]])
- {
- // 说明要赋值的属性是NSObject的子类
- id value = [NSObject parse:targetCls dictionary:idkeyValue itemClass:cls];
- [self setValue:value forKey:key];
- }
- else if ([idkeyValue isKindOfClass:[NSArray class]])
- {
- // NSMutableArray *array = [[NSMutableArray alloc] init];
- // for (NSDictionary *dic in idkeyValue ) {
- // if (dic) {
- // id value = [NSObject parse:cls dictionary:dic];
- // [array addObject:value];
- // }
- // }
- //
- // [self setValue:array forKey:key];
- // [array release];
- // 说明要赋值的属性是一个列表
- NSMutableArray *arrayValue = (NSMutableArray *)[NSObject loadItem:cls fromArrayDictionary:idkeyValue];
-
- [self setValue:arrayValue forKey:key];
- }
- }
- // 遍历
- - (void)enumerateProperty:(NSString *)propertyName value:(id)idvalue propertyDictionary:(NSDictionary *)propertyKeys
- {
- if ([idvalue isKindOfClass:[NSNull class]])
- {
- NSString *proClsName = [propertyKeys objectForKey:propertyName];
- if ([proClsName hasPrefix:@"T@"])
- {
- [self setValue:nil forKey:propertyName];
- }
- else
- {
- NSNumber *num = [NSNumber numberWithInteger:0];
- [self setValue:num forKey:propertyName];
- }
- }
- else
- {
- if (idvalue)
- {
- NSString *proClsName = [propertyKeys objectForKey:propertyName];
-
- if ([proClsName hasPrefix:@"T@"])
- {
- NSRange range = [proClsName rangeOfString:@"\""];
- NSString *test = [proClsName substringFromIndex:range.location+1];
- range = [test rangeOfString:@"\""];
- NSString *realClassName = [test substringToIndex:range.location];
- Class proCls = NSClassFromString(realClassName);
-
- if ([idvalue isKindOfClass:proCls] && ![idvalue isKindOfClass:[NSMutableArray class]] && ![idvalue isKindOfClass:[NSMutableDictionary class]])
- {
- [self setValue:idvalue forKey:propertyName];
- }
- else
- {
- [self setValueForPropertyValue:idvalue forKey:propertyName propertyClass:proCls tagretClass:proCls];
- }
- }
- else
- {
- if ([idvalue isKindOfClass:[NSDecimalNumber class]]) {
- NSDecimalNumber *num = (NSDecimalNumber *)idvalue;
- [self setValue:num forKey:propertyName];
- }
- else
- {
- NSNumber *num = (NSNumber *)idvalue;
- [self setValue:num forKey:propertyName];
-
- }
- }
- }
-
- }
-
- }
- + (id)parse:(Class)aClass dictionary:(NSDictionary *)dict
- {
-
- id aClassInstance = [[aClass alloc] init];
- CommonAutoRelease(aClassInstance);
-
- // 因JSON返回的字段中有id
- // 所以对此数据作特处理
- id idTagValue = [dict objectForKey:kServiceTag_ID];
- if (idTagValue) {
- [aClassInstance setIdPropertyValue:idTagValue];
- }
-
- // 将返回的Json键与aClassInstance的属性列表进行一次对比,找出要赋值的属性,以减少不必要的运算
- NSDictionary *propertyKeys = [aClassInstance enumerateKeysInDictionary:dict];
- CommonRetain(propertyKeys);
-
- NSArray *propertyKeysArray = [propertyKeys allKeys];
-
- // 逐一对相关的属性进行设置
- for (unsigned int i = 0 ; i < propertyKeysArray.count; i++ )
- {
- NSString *propertyName = [propertyKeysArray objectAtIndex:i];
- id idvalue = [dict objectForKey:propertyName];
-
- // propertyName:要设置的属性名
- // idvalue:对应的值
- [aClassInstance enumerateProperty:propertyName value:idvalue propertyDictionary:propertyKeys];
- }
-
- CommonRelease(propertyKeys);
- return aClassInstance;
- }
- - (NSMutableDictionary *)propertyListOfClass:(Class)class
- {
- NSMutableDictionary *dic = [NSMutableDictionary dictionary];
-
- unsigned int propertyCount = 0;
- objc_property_t *propertyList = class_copyPropertyList(class, &propertyCount);
- for (unsigned int i = 0 ; i < propertyCount; i++ )
- {
- const char *pcName = property_getName(propertyList[i]);
- NSString *propertyName = [NSString stringWithCString:pcName encoding:NSUTF8StringEncoding];
-
- const char *proClsNameCStr = property_getAttributes(propertyList[i]);
- NSString *proClsName = [NSString stringWithCString:proClsNameCStr encoding:NSUTF8StringEncoding];
- [dic setObject:proClsName forKey:propertyName];
-
- }
- free(propertyList);
-
- if (class != [NSObject class])
- {
- // 去掉NSObject里面的属性
- NSMutableDictionary *ObjectClass = [self propertyListOfClass:[NSObject class]];
-
- [dic removeObjectsForKeys:[ObjectClass allKeys]];
-
- // iOS8以前dic会加上这几个不用的键值 @[@"debugDescription", @"description", @"hash", @"superclass"]
- if (![IOSDeviceConfig sharedConfig].isIOS7Later)
- {
- [dic removeObjectsForKeys:@[@"debugDescription", @"description", @"hash", @"superclass"]];
- }
- // {
- // debugDescription = "T@\"NSString\",R,C";
- // description = "T@\"NSString\",R,C";
- // hash = "TQ,R";
- // pageIndex = "Tq,N,V_pageIndex";
- // pageSize = "Tq,N,V_pageSize";
- // superclass = "T#,R";
- // }
- }
-
-
-
-
- return dic;
- }
- // 返回class的所有属性列表(包括当前类至NSObject类的之间所有继承关系对象的列表)
- - (void)propertyListOfClass:(Class)class propertyList:(NSMutableDictionary *)propertyDic
- {
- if (class == [NSObject class])
- {
- return;
- }
- else
- {
- // 添加class属性列表到返回结果里面
- NSDictionary *selfDic = [self propertyListOfClass:class];
- [propertyDic addEntriesFromDictionary:selfDic];
-
- // 继续查找class的父类
- Class superClass = class_getSuperclass(class);
- [self propertyListOfClass:superClass propertyList:propertyDic];
- }
-
- }
- // 通过返回的Json字典valueDict的keys,过滤出需要设置的属性名名称及对应的类型
- // 返回:过滤后需要设置的()
- - (NSDictionary *)enumerateKeysInDictionary:(NSDictionary *)valueDict
- {
- NSUInteger propertyCount = 0;
-
- NSMutableDictionary *propertyKeys = [[NSMutableDictionary alloc] init];
- CommonAutoRelease(propertyKeys);
-
- NSMutableDictionary *dic = [NSMutableDictionary dictionary];
- [self propertyListOfClass:[self class] propertyList:dic];
-
- NSArray *dicKeys = [dic allKeys];
- propertyCount = dicKeys.count;
-
- NSArray *valueDictKeys = [valueDict allKeys];
-
- for (int i = 0; i < propertyCount; i++) {
- NSString *propertyName = [dicKeys objectAtIndex:i];
-
- if ([valueDictKeys containsObject:propertyName])
- {
- [propertyKeys setObject:[dic valueForKey:propertyName] forKey:propertyName];
- }
- }
-
- return propertyKeys;
- }
- - (void)enumerateProperty:(NSString *)propertyName value:(id)idvalue propertyDictionary:(NSDictionary *)propertyKeys itemClass:(Class)itemClass
- {
- if ([idvalue isKindOfClass:[NSNull class]])
- {
- [self setValue:nil forKey:propertyName];
- }
- else
- {
- if (idvalue)
- {
- NSString *proClsName = [propertyKeys objectForKey:propertyName];
-
- if ([proClsName hasPrefix:@"T@"])
- {
- NSRange range = [proClsName rangeOfString:@"\""];
- NSString *test = [proClsName substringFromIndex:range.location+1];
- range = [test rangeOfString:@"\""];
- NSString *realClassName = [test substringToIndex:range.location];
- Class proCls = NSClassFromString(realClassName);
-
- if ([idvalue isKindOfClass:proCls] && ![idvalue isKindOfClass:[NSMutableArray class]] && ![idvalue isKindOfClass:[NSMutableDictionary class]])
- {
- [self setValue:idvalue forKey:propertyName];
- }
- else
- {
- [self setValueForPropertyValue:idvalue forKey:propertyName propertyClass:itemClass tagretClass:proCls];
- }
- }
- else
- {
- if ([idvalue isKindOfClass:[NSDecimalNumber class]]) {
- NSDecimalNumber *num = (NSDecimalNumber *)idvalue;
- [self setValue:num forKey:propertyName];
- }
- else
- {
- NSNumber *num = (NSNumber *)idvalue;
- [self setValue:num forKey:propertyName];
-
- }
-
- }
- }
-
- }
-
- }
- + (id)parse:(Class)aClass dictionary:(NSDictionary *)dict itemClass:(Class)itemClass
- {
- id aClassInstance = [[aClass alloc] init];
- CommonAutoRelease(aClassInstance);
-
- // 因JSON返回的字段中有id
- // 所以对此数据作特处理
- id idTagValue = [dict objectForKey:kServiceTag_ID];
- if (idTagValue) {
- [aClassInstance setIdPropertyValue:idTagValue];
- }
-
- NSDictionary *propertyKeys = [aClassInstance enumerateKeysInDictionary:dict];
- CommonRetain(propertyKeys);
-
- NSArray *propertyKeysArray = [propertyKeys allKeys];
- for (unsigned int i = 0 ; i < propertyKeysArray.count; i++ )
- {
- NSString *propertyName = [propertyKeysArray objectAtIndex:i];
- id idvalue = [dict objectForKey:propertyName];
- [aClassInstance enumerateProperty:propertyName value:idvalue propertyDictionary:propertyKeys itemClass:itemClass];
-
- }
- CommonRelease(propertyKeys);
- // [propertyKeys release];
-
- return aClassInstance;
-
- }
- + (id)parse:(Class)aClass jsonString:(NSString *)json
- {
- NSDictionary *dic = [json objectFromJSONString];
- CustomMessageModel *customMessageModel = [CustomMessageModel mj_objectWithKeyValues:json];
- if (customMessageModel.type == 82) {
- NSLog(@"收到广播消息了");
-
-
-
- }
-
- return dic ? [NSObject parse:aClass dictionary:dic] : nil;
- }
- + (id)parse:(Class)aClass jsonString:(NSString *)json itemClass:(Class)itemClass
- {
- NSDictionary *dic = [json objectFromJSONString];
- return dic ? [NSObject parse:aClass dictionary:dic itemClass:itemClass] : nil;
- }
- + (NSMutableArray *)loadItem:(Class)itemClass fromDictionary:(NSArray *)arraydict
- {
- NSMutableArray *array = [[NSMutableArray alloc] init];
-
- for (NSDictionary *dic in arraydict ) {
- if (dic) {
- // 遍历数据中单个字典元素,将期反序列化成itemClass对象实例
- id value = [NSObject parse:itemClass dictionary:dic];
- [array addObject:value];
- }
- }
- return CommonReturnAutoReleased(array);
- }
- + (NSMutableArray *)loadItem:(Class)itemClass fromJsonString:(NSString *)json
- {
- NSArray *dic = [json objectFromJSONString];
- return dic ? [NSObject loadItem:itemClass fromJsonString:json] : nil;
- }
- - (id)serializeToJsonObject
- {
- if ([NSJSONSerialization isValidJSONObject:self])
- {
- return self;
- }
-
- if ([self isMemberOfClass:[NSObject class]])
- {
- // 解析到此
- return nil;
- }
-
- NSMutableDictionary *jsonDic = [NSMutableDictionary dictionary];
-
- // 将返回的Json键与aClassInstance的属性列表进行一次对比,找出要赋值的属性,以减少不必要的运算
- NSMutableDictionary *propertyKeys = [NSMutableDictionary dictionary];
-
- [self propertyListOfClass:[self class] propertyList:propertyKeys];
-
- NSArray *propertyKeysArray = [propertyKeys allKeys];
-
- // 逐一对相关的属性进行设置
- for (unsigned int i = 0 ; i < propertyKeysArray.count; i++ )
- {
- NSString *propertyName = [propertyKeysArray objectAtIndex:i];
-
- NSString *propertType = [propertyKeys valueForKey:propertyName];
-
- if ([propertType hasPrefix:@"T@"])
- {
- // 对应类
- id idvalue = [self valueForKey:propertyName];
- if (idvalue)
- {
- if ([idvalue isKindOfClass:[NSString class]])
- {
- [jsonDic setObject:idvalue forKey:propertyName];
- }
- else
- {
- id idvalueJson = [idvalue serializeToJsonObject];
- if (idvalueJson)
- {
- [jsonDic setObject:idvalueJson forKey:propertyName];
- }
- }
- }
-
- }
- else
- {
- // 基本数据类型
- id idvalue = [self valueForKey:propertyName];
- [jsonDic setObject:idvalue forKey:propertyName];
- }
- }
-
- return jsonDic;
- }
- // 把对象自身的属性序列化成Json字典, 以属性名作为键值
- - (id)serializeSelfPropertyToJsonObject
- {
- if ([NSJSONSerialization isValidJSONObject:self])
- {
- return self;
- }
-
- if ([self isMemberOfClass:[NSObject class]])
- {
- // 解析到此
- return nil;
- }
-
- NSMutableDictionary *jsonDic = [NSMutableDictionary dictionary];
-
- // 将返回的Json键与aClassInstance的属性列表进行一次对比,找出要赋值的属性,以减少不必要的运算
- NSMutableDictionary *propertyKeys = [self propertyListOfClass:[self class]];
-
- NSArray *propertyKeysArray = [propertyKeys allKeys];
-
- // 逐一对相关的属性进行设置
- for (unsigned int i = 0 ; i < propertyKeysArray.count; i++ )
- {
- NSString *propertyName = [propertyKeysArray objectAtIndex:i];
-
- NSString *propertType = [propertyKeys valueForKey:propertyName];
-
- if ([propertType hasPrefix:@"T@"])
- {
- // 对应类
- id idvalue = [self valueForKey:propertyName];
- if (idvalue)
- {
- if ([idvalue isKindOfClass:[NSString class]])
- {
- NSString *stringValue = (NSString *)idvalue;
- if (stringValue.length)
- {
- [jsonDic setObject:idvalue forKey:propertyName];
- }
- else
- {
- [jsonDic setObject:@"" forKey:propertyName];
- }
- }
- else
- {
- id idvalueJson = [idvalue serializeToJsonObject];
- if (idvalueJson)
- {
- [jsonDic setObject:idvalueJson forKey:propertyName];
- }
- }
- }
-
- }
- else
- {
- // 基本数据类型
- id idvalue = [self valueForKey:propertyName];
- [jsonDic setObject:idvalue forKey:propertyName];
- }
-
- }
-
- return jsonDic;
- }
- + (id)loadInfo:(Class)aclass withKey:(NSString *)key
- {
- NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
- NSString *loginInfo = [ud objectForKey:key];
- if (loginInfo)
- {
- id ret = [NSObject parse:[aclass class] jsonString:loginInfo];
- if (ret)
- {
- return ret;
- }
- else
- {
- return loginInfo;
- }
- }
- return nil;
- }
- + (void)saveInfo:(NSObject *)obj withKey:(NSString *)key
- {
- NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
- if (obj)
- {
- if ([obj isKindOfClass:[NSString class]])
- {
- [ud setObject:obj forKey:key];
- }
- else
- {
- NSDictionary *dic = [obj serializeToJsonObject];
-
- if ([NSJSONSerialization isValidJSONObject:dic])
- {
- NSError *error = nil;
- NSData *data = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:&error];
- if(error)
- {
- DebugLog(@"存储失败");
- }
- NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
- [ud setObject:str forKey:key];
- }
- }
-
- [ud synchronize];
- }
- else
- {
- [ud removeObjectForKey:key];
- }
- }
- @end
- @implementation NSArray (serializeToJsonObject)
- - (id)serializeToJsonObject
- {
- if ([NSJSONSerialization isValidJSONObject:self])
- {
- return self;
- }
-
- NSMutableArray *array = [NSMutableArray array];
- for (id obj in self)
- {
- id jsonObj = [obj serializeToJsonObject];
- if (jsonObj)
- {
- [array addObject:jsonObj];
- }
- }
-
- if (array.count)
- {
- if ([NSJSONSerialization isValidJSONObject:array])
- {
- return array;
- }
- }
-
- DebugLog(@"[%@] can't convert to vaild Json", self);
- return nil;
- }
- @end
- @implementation NSDictionary (serializeToJsonObject)
- - (id)serializeToJsonObject
- {
- if ([NSJSONSerialization isValidJSONObject:self])
- {
- return self;
- }
- return nil;
- }
- @end
|