How to convert NSDictionary to custom object

22,464

Solution 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];

Solution 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];
}

Solution 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];
    }
}

Solution 4

this will be more convenient for you :

 - (instancetype)initWithDictionary:(NSDictionary*)dictionary {
        if (self = [super init]) {
            [self setValuesForKeysWithDictionary:dictionary];}
        return self;
    }
Share:
22,464
1110
Author by

1110

Updated on July 05, 2022

Comments

  • 1110
    1110 almost 2 years

    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?

  • Balazs Nemeth
    Balazs Nemeth over 10 years
    If you have much objects, you must implement initWithDictionay one by one... There is some more flexible solutions e.g.::github.com/Infusion-apps/IAModelBase
  • Hitendra Solanki
    Hitendra Solanki almost 9 years
    this will crash, if any field is missing
  • Arpit B Parekh
    Arpit B Parekh over 7 years
    Also see the issue , github.com/oarrabi/IAModelBase/issues but we can manage it. Ya it is good. If any query please contact me.
  • Brian Kalski
    Brian Kalski over 7 years
    This should help. Check the object for the fieldName before setting the value. if ([object respondsToSelector:NSSelectorFromString(fieldName)]) { [object setValue:[dictionary objectForKey:fieldName] forKey:fieldName]; } } }