可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a json object:
@interface Order : NSObject @property (nonatomic, retain) NSString *OrderId; @property (nonatomic, retain) NSString *Title; @property (nonatomic, retain) NSString *Weight; - (NSMutableDictionary *)toNSDictionary; ... - (NSMutableDictionary *)toNSDictionary { NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; [dictionary setValue:self.OrderId forKey:@"OrderId"]; [dictionary setValue:self.Title forKey:@"Title"]; [dictionary setValue:self.Weight forKey:@"Weight"]; return dictionary; }
In string this is:
{ "Title" : "test", "Weight" : "32", "OrderId" : "55" }
I get string JSON with code:
NSMutableDictionary* str = [o toNSDictionary]; NSError *writeError = nil; NSData *jsonData = [NSJSONSerialization dataWithJSONObject:str options:NSJSONWritingPrettyPrinted error:&writeError]; NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
Now I need to create and map object from JSON string:
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; NSError *e; NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:jsonData options:nil error:&e];
This returns me filled NSDictionary. What should I do to get object from this dictionary?
回答1:
Add a new initWithDictionary:
method to Order
:
- (instancetype)initWithDictionary:(NSDictionary*)dictionary { if (self = [super init]) { self.OrderId = dictionary[@"OrderId"]; self.Title = dictionary[@"Title"]; self.Weight = dictionary[@"Weight"]; } return self; }
Don't forget to add initWithDictionary
's signature to Order.h
file
In the method where you get JSON:
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; NSError *e; NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:jsonData options:nil error:&e]; Order *order = [[Order alloc] initWithDictionary:dict];
回答2:
If the property names on your object match the keys in the JSON string you can do the following:
To map the JSON string to your Object you need to convert the string into a NSDictionary first and then you can use a method on NSObject that uses Key-Value Coding to set each property.
NSError *error = nil; NSData *jsonData = ...; // e.g. [myJSONString dataUsingEncoding:NSUTF8Encoding]; NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingOptionsAllowFragments error:&error]; MyObject *object = [[MyObject alloc] init]; [object setValuesForKeysWithDictionary:jsonDictionary];
If the keys do not match you can override the instance method of NSObject -[NSObject valueForUndefinedKey:]
in your object class.
To map you Object to JSON you can use the Objective-C runtime to do it automatically. The following works with any NSObject subclass:
#import <objc/runtime.h> - (NSDictionary *)dictionaryValue { NSMutableArray *propertyKeys = [NSMutableArray array]; Class currentClass = self.class; while ([currentClass superclass]) { // avoid printing NSObject's attributes unsigned int outCount, i; objc_property_t *properties = class_copyPropertyList(currentClass, &outCount); for (i = 0; i < outCount; i++) { objc_property_t property = properties[i]; const char *propName = property_getName(property); if (propName) { NSString *propertyName = [NSString stringWithUTF8String:propName]; [propertyKeys addObject:propertyName]; } } free(properties); currentClass = [currentClass superclass]; } return [self dictionaryWithValuesForKeys:propertyKeys]; }
回答3:
Assuming that your properties names and the dictionary keys are the same, you can use this function to convert any object
- (void) setObject:(id) object ValuesFromDictionary:(NSDictionary *) dictionary { for (NSString *fieldName in dictionary) { [object setValue:[dictionary objectForKey:fieldName] forKey:fieldName]; } }
回答4:
this will be more convenient for you :
- (instancetype)initWithDictionary:(NSDictionary*)dictionary { if (self = [super init]) { [self setValuesForKeysWithDictionary:dictionary];} return self; }
回答5:
The perfect way to do this is by using a library for serialization/deserialization many libraries are available but one i like is JagPropertyConverter https://github.com/jagill/JAGPropertyConverter
it can convert your Custom object into NSDictionary and vice versa
even it support to convert dictionary or array or any custom object within your object (i.e Composition)
JAGPropertyConverter *converter = [[JAGPropertyConverter alloc]init]; converter.classesToConvert = [NSSet setWithObjects:[Order class], nil]; @interface Order : NSObject @property (nonatomic, retain) NSString *OrderId; @property (nonatomic, retain) NSString *Title; @property (nonatomic, retain) NSString *Weight; @end //For Dictionary to Object (AS IN YOUR CASE) NSMutableDictionary *dictionary = [[NSMutableDictionary alloc] init]; [dictionary setValue:self.OrderId forKey:@"OrderId"]; [dictionary setValue:self.Title forKey:@"Title"]; [dictionary setValue:self.Weight forKey:@"Weight"]; Order *order = [[Order alloc]init]; [converter setPropertiesOf:order fromDictionary:dictionary]; //For Object to Dictionary Order *order = [[Order alloc]init]; order.OrderId = @"10"; order.Title = @"Title; order.Weight = @"Weight"; NSDictionary *dictPerson = [converter convertToDictionary:person];
回答6:
Define your custom class inherits from "AutoBindObject". Declare properties which has the same name with keys in NSDictionary. Then call method:
[customObject loadFromDictionary:dic];
Actually, we can customize class to map different property names to keys in dictionary. Beside that, we can bind nested objects.
Please have a look to this demo. The usage is easy:
https://github.com/caohuuloc/AutoBindObject