小墨的iOS移动端APP代码

NSObject+EasyJSON.mm 16KB

    // Created by EasyIOS on 14-4-10. // Copyright (c) 2014年 zhuchao. All rights reserved. // #import "NSObject+EasyJSON.h" #import "Easy_Runtime.h" #import "NSObject+EasyTypeConversion.h" #import "NSDictionary+EasyExtend.h" // ---------------------------------- // Source code // ---------------------------------- #pragma mark - @implementation NSObject(EasyJSON) + (id)objectsFromArray:(id)arr { if ( nil == arr ) return nil; if ( NO == [arr isKindOfClass:[NSArray class]] ) return nil; NSMutableArray * results = [NSMutableArray array]; for ( NSObject * obj in (NSArray *)arr ) { if ( [obj isKindOfClass:[NSDictionary class]] ) { NSDictionary *dict = [self objectFromDictionary:obj]; if ( dict ) { [results addObject:dict]; } } else { [results addObject:obj]; } } return results; } + (id)objectsFromAny:(id)any { if ( nil == any ) { return nil; } if ( [any isKindOfClass:[NSArray class]] ) { return [self objectsFromArray:any]; } else if ( [any isKindOfClass:[NSDictionary class]] ) { id obj = [self objectFromDictionary:any]; if ( nil == obj ) return nil; if ( [obj isKindOfClass:[NSArray class]] ) { return obj; } else { return [NSArray arrayWithObject:obj]; } } else if ( [any isKindOfClass:[NSString class]] ) { id obj = [self objectFromString:any]; if ( nil == obj ) return nil; if ( [obj isKindOfClass:[NSArray class]] ) { return obj; } else { return [NSArray arrayWithObject:obj]; } } else if ( [any isKindOfClass:[NSData class]] ) { id obj = [self objectFromData:any]; if ( nil == obj ) return nil; if ( [obj isKindOfClass:[NSArray class]] ) { return obj; } else { return [NSArray arrayWithObject:obj]; } } else { return [NSArray arrayWithObject:any]; } } + (id)objectFromDictionary:(id)dict { if ( nil == dict ) { return nil; } if ( NO == [dict isKindOfClass:[NSDictionary class]] ) { return nil; } return (NSDictionary *)dict; } + (id)objectFromString:(id)str { if ( nil == str ) { return nil; } if ( NO == [str isKindOfClass:[NSString class]] ) { return nil; } NSError * error = nil; NSObject * obj = [NSJSONSerialization JSONObjectWithData:[str dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&error]; if ( nil == obj ) { NSLog( @"%@", error ); return nil; } if ( [obj isKindOfClass:[NSDictionary class]] ) { return [self objectFromDictionary:obj]; } else if ( [obj isKindOfClass:[NSArray class]] ) { NSMutableArray * array = [NSMutableArray array]; for ( NSObject * elem in (NSArray *)obj ) { if ( [elem isKindOfClass:[NSDictionary class]] ) { NSDictionary * result = [self objectFromDictionary:elem]; if ( result ) { [array addObject:elem]; } } } return array; } else if ( [BeeTypeEncoding isAtomClass:[obj class]] ) { return obj; } return nil; } + (id)objectFromData:(id)data { if ( nil == data ) { return nil; } if ( NO == [data isKindOfClass:[NSData class]] ) { return nil; } NSError * error = nil; NSObject * obj = [NSJSONSerialization JSONObjectWithData:(NSData *)data options:0 error:&error]; if(obj == nil){ NSLog(@"%@",error); } if ( obj ) { if ( [obj isKindOfClass:[NSDictionary class]] ) { return [self objectFromDictionary:obj]; } else if ( [obj isKindOfClass:[NSArray class]] ) { return [self objectsFromArray:obj]; } } return nil; } + (id)objectFromAny:(id)any { if ( [any isKindOfClass:[NSArray class]] ) { return [self objectsFromArray:any]; } else if ( [any isKindOfClass:[NSDictionary class]] ) { return [self objectFromDictionary:any]; } else if ( [any isKindOfClass:[NSString class]] ) { return [self objectFromString:any]; } else if ( [any isKindOfClass:[NSData class]] ) { return [self objectFromData:any]; } return any; } - (id)objectToDictionary { return [self objectToDictionaryUntilRootClass:nil]; } - (id)objectToDictionaryUntilRootClass:(Class)rootClass { NSMutableDictionary * result = [NSMutableDictionary dictionary]; if ( [self isKindOfClass:[NSDictionary class]] ) { NSDictionary * dict = (NSDictionary *)self; for ( NSString * key in dict.allKeys ) { NSObject * obj = [dict objectForKey:key]; if ( obj ) { NSUInteger propertyType = [BeeTypeEncoding typeOfObject:obj]; if ( BeeTypeEncoding.NSNUMBER == propertyType ) { [result setObject:obj forKey:key]; } else if ( BeeTypeEncoding.NSSTRING == propertyType ) { [result setObject:obj forKey:key]; } else if ( BeeTypeEncoding.NSARRAY == propertyType ) { NSMutableArray * array = [NSMutableArray array]; for ( NSObject * elem in (NSArray *)obj ) { NSDictionary * dict = [elem objectToDictionaryUntilRootClass:rootClass]; if ( dict ) { [array addObject:dict]; } else { if ( [BeeTypeEncoding isAtomClass:[elem class]] ) { [array addObject:elem]; } } } [result setObject:array forKey:key]; } else if ( BeeTypeEncoding.NSDICTIONARY == propertyType ) { NSMutableDictionary * dict = [NSMutableDictionary dictionary]; for ( NSString * key in ((NSDictionary *)obj).allKeys ) { NSObject * val = [(NSDictionary *)obj objectForKey:key]; if ( val ) { NSDictionary * subresult = [val objectToDictionaryUntilRootClass:rootClass]; if ( subresult ) { [dict setObject:subresult forKey:key]; } else { if ( [BeeTypeEncoding isAtomClass:[val class]] ) { [dict setObject:val forKey:key]; } } } } [result setObject:dict forKey:key]; } else if ( BeeTypeEncoding.NSDATE == propertyType ) { [result setObject:[obj description] forKey:key]; } else { obj = [obj objectToDictionaryUntilRootClass:rootClass]; if ( obj ) { [result setObject:obj forKey:key]; } else { [result setObject:[NSDictionary dictionary] forKey:key]; } } } // else // { // [result setObject:[NSNull null] forKey:key]; // } } } else { for ( Class clazzType = [self class];; ) { if ( rootClass ) { if ( clazzType == rootClass ) break; } else { if ( [BeeTypeEncoding isAtomClass:clazzType] ) break; } unsigned int propertyCount = 0; objc_property_t * properties = class_copyPropertyList( clazzType, &propertyCount ); for ( NSUInteger i = 0; i < propertyCount; i++ ) { const char * name = property_getName(properties[i]); const char * attr = property_getAttributes(properties[i]); NSString * propertyName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding]; NSUInteger propertyType = [BeeTypeEncoding typeOf:attr]; NSObject * obj = [self valueForKey:propertyName]; if ( obj ) { if ( BeeTypeEncoding.NSNUMBER == propertyType ) { [result setObject:obj forKey:propertyName]; } else if ( BeeTypeEncoding.NSSTRING == propertyType ) { [result setObject:obj forKey:propertyName]; } else if ( BeeTypeEncoding.NSARRAY == propertyType ) { NSMutableArray * array = [NSMutableArray array]; for ( NSObject * elem in (NSArray *)obj ) { NSUInteger elemType = [BeeTypeEncoding typeOfObject:elem]; if ( BeeTypeEncoding.NSNUMBER == elemType ) { [array addObject:elem]; } else if ( BeeTypeEncoding.NSSTRING == elemType ) { [array addObject:elem]; } else { NSDictionary * dict = [elem objectToDictionaryUntilRootClass:rootClass]; if ( dict ) { [array addObject:dict]; } else { if ( [BeeTypeEncoding isAtomClass:[elem class]] ) { [array addObject:elem]; } } } } [result setObject:array forKey:propertyName]; } else if ( BeeTypeEncoding.NSDICTIONARY == propertyType ) { NSMutableDictionary * dict = [NSMutableDictionary dictionary]; for ( NSString * key in ((NSDictionary *)obj).allKeys ) { NSObject * val = [(NSDictionary *)obj objectForKey:key]; if ( val ) { NSDictionary * subresult = [val objectToDictionaryUntilRootClass:rootClass]; if ( subresult ) { [dict setObject:subresult forKey:key]; } else { if ( [BeeTypeEncoding isAtomClass:[val class]] ) { [dict setObject:val forKey:key]; } } } } [result setObject:dict forKey:propertyName]; } else if ( BeeTypeEncoding.NSDATE == propertyType ) { [result setObject:[obj description] forKey:propertyName]; } else { obj = [obj objectToDictionaryUntilRootClass:rootClass]; if ( obj ) { [result setObject:obj forKey:propertyName]; } else { [result setObject:[NSDictionary dictionary] forKey:propertyName]; } } } // else // { // [result setObject:[NSNull null] forKey:propertyName]; // } } free( properties ); clazzType = class_getSuperclass( clazzType ); if ( nil == clazzType ) break; } } return result.count ? result : nil; } - (id)objectZerolize { return [self objectZerolizeUntilRootClass:nil]; } - (id)objectZerolizeUntilRootClass:(Class)rootClass { for ( Class clazzType = [self class];; ) { if ( rootClass ) { if ( clazzType == rootClass ) break; } else { if ( [BeeTypeEncoding isAtomClass:clazzType] ) break; } unsigned int propertyCount = 0; objc_property_t * properties = class_copyPropertyList( clazzType, &propertyCount ); for ( NSUInteger i = 0; i < propertyCount; i++ ) { const char * name = property_getName(properties[i]); const char * attr = property_getAttributes(properties[i]); NSString * propertyName = [NSString stringWithCString:name encoding:NSUTF8StringEncoding]; NSUInteger propertyType = [BeeTypeEncoding typeOfAttribute:attr]; if ( BeeTypeEncoding.NSNUMBER == propertyType ) { [self setValue:[NSNumber numberWithInt:0] forKey:propertyName]; } else if ( BeeTypeEncoding.NSSTRING == propertyType ) { [self setValue:@"" forKey:propertyName]; } else if ( BeeTypeEncoding.NSARRAY == propertyType ) { [self setValue:[NSMutableArray array] forKey:propertyName]; } else if ( BeeTypeEncoding.NSDICTIONARY == propertyType ) { [self setValue:[NSMutableDictionary dictionary] forKey:propertyName]; } else if ( BeeTypeEncoding.NSDATE == propertyType ) { [self setValue:[NSDate dateWithTimeIntervalSince1970:0] forKey:propertyName]; } else if ( BeeTypeEncoding.OBJECT == propertyType ) { Class clazz = [BeeTypeEncoding classOfAttribute:attr]; if ( clazz ) { NSObject * newObj = [[clazz alloc] init]; [self setValue:newObj forKey:propertyName]; } else { [self setValue:nil forKey:propertyName]; } } else { [self setValue:nil forKey:propertyName]; } } free( properties ); clazzType = class_getSuperclass( clazzType ); if ( nil == clazzType ) break; } return self; } - (id)objectToString { return [self objectToStringUntilRootClass:nil]; } - (id)objectToStringUntilRootClass:(Class)rootClass { NSString * json = nil; NSUInteger propertyType = [BeeTypeEncoding typeOfObject:self]; if ( BeeTypeEncoding.NSNUMBER == propertyType ) { json = [self asNSString]; } else if ( BeeTypeEncoding.NSSTRING == propertyType ) { json = [self asNSString]; } else if ( BeeTypeEncoding.NSARRAY == propertyType ) { NSMutableArray * array = [NSMutableArray array]; for ( NSObject * elem in (NSArray *)self ) { NSDictionary * dict = [elem objectToDictionaryUntilRootClass:rootClass]; if ( dict ) { [array addObject:dict]; } else { if ( [BeeTypeEncoding isAtomClass:[elem class]] ) { [array addObject:elem]; } } } json = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:array options:NSJSONWritingPrettyPrinted error:nil] encoding:NSUTF8StringEncoding]; } else if ( BeeTypeEncoding.NSDICTIONARY == propertyType ) { NSDictionary * dict = [self objectToDictionaryUntilRootClass:rootClass]; if ( dict ) { json = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil] encoding:NSUTF8StringEncoding]; } } else if ( BeeTypeEncoding.NSDATE == propertyType ) { json = [self description]; } else { NSDictionary * dict = [self objectToDictionaryUntilRootClass:rootClass]; if ( nil == dict ) { dict = [NSDictionary dictionary]; } json = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil] encoding:NSUTF8StringEncoding]; } if ( nil == json || 0 == json.length ) return nil; return [NSMutableString stringWithString:json]; } - (id)objectToData { return [self objectToDataUntilRootClass:nil]; } - (id)objectToDataUntilRootClass:(Class)rootClass { NSString * string = [self objectToStringUntilRootClass:rootClass]; if ( nil == string ) return nil; return [string dataUsingEncoding:NSUTF8StringEncoding]; } - (id)serializeObject { NSUInteger type = [BeeTypeEncoding typeOfObject:self]; if ( BeeTypeEncoding.NSNUMBER == type ) { return self; } else if ( BeeTypeEncoding.NSSTRING == type ) { return self; } else if ( BeeTypeEncoding.NSDATE == type ) { return self; } else if ( BeeTypeEncoding.NSARRAY == type ) { NSArray * array = (NSArray *)self; NSMutableArray * result = [NSMutableArray array]; for ( NSObject * elem in array ) { NSObject * val = [elem serializeObject]; if ( val ) { [result addObject:val]; } } return result; } else if ( BeeTypeEncoding.NSDICTIONARY == type ) { NSDictionary * dict = (NSDictionary *)self; NSMutableDictionary * result = [NSMutableDictionary dictionary]; for ( NSString * key in dict.allKeys ) { NSObject * val = [dict objectForKey:key]; NSObject * val2 = [val serializeObject]; if ( val2 ) { [result setObject:val2 forKey:key]; } } return result; } else if ( BeeTypeEncoding.OBJECT == type ) { return [self objectToDictionary]; } return nil; } + (id)unserializeObject:(id)obj { NSUInteger type = [BeeTypeEncoding typeOfObject:obj]; if ( BeeTypeEncoding.NSNUMBER == type ) { return self; } else if ( BeeTypeEncoding.NSSTRING == type ) { return [self objectFromString:obj]; } else if ( BeeTypeEncoding.NSDATE == type ) { return self; } else if ( BeeTypeEncoding.NSARRAY == type ) { return [self objectsFromArray:obj]; } else if ( BeeTypeEncoding.NSDICTIONARY == type ) { return [self objectFromDictionary:obj]; } else if ( BeeTypeEncoding.OBJECT == type ) { return self; } return nil; } -(BOOL)isNotEmpty{ return !(self == nil || [self isKindOfClass:[NSNull class]] || ([self respondsToSelector:@selector(length)] && [(NSData *)self length] == 0) || ([self respondsToSelector:@selector(count)] && [(NSArray *)self count] == 0)); } @end