How to convert NSDictionary to custom object

匿名 (未验证) 提交于 2019-12-03 03:05:02

问题:

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



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!