如何将NSDictionary转换为自定义对象

时间:2022-12-25 13:50:29

I have a json object:

我有一个json对象:

@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:

我用代码得到字符串JSON:

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:

现在我需要从JSON字符串创建和映射对象:

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?

这将返回我填写的NSDictionary。我该怎么做才能从这本字典中获取对象?

6 个解决方案

#1


19  

Add a new initWithDictionary: method to Order:

在Order中添加一个新的initWithDictionary:方法:

- (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

不要忘记将initWithDictionary的签名添加到Order.h文件中

In the method where you get JSON:

在获得JSON的方法中:

NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSError *e;
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:jsonData options:nil error:&e];
Order *order = [[Order alloc] initWithDictionary:dict];

#2


11  

If the property names on your object match the keys in the JSON string you can do the following:

如果对象上的属性名称与JSON字符串中的键匹配,则可以执行以下操作:

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.

要将JSON字符串映射到Object,您需要先将字符串转换为NSDictionary,然后在NSObject上使用一个使用键值编码来设置每个属性的方法。

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.

如果键不匹配,则可以在对象类中覆盖NSObject的实例方法 - [NSObject valueForUndefinedKey:]。

To map you Object to JSON you can use the Objective-C runtime to do it automatically. The following works with any NSObject subclass:

要将Object映射到JSON,您可以使用Objective-C运行时自动执行此操作。以下适用于任何NSObject子类:

#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


4  

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


3  

this will be more convenient for you :

这对你来说会更方便:

 - (instancetype)initWithDictionary:(NSDictionary*)dictionary {
        if (self = [super init]) {
            [self setValuesForKeysWithDictionary:dictionary];}
        return self;
    }

#5


0  

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

完成此操作的最佳方法是使用库进行序列化/反序列化,许多库都可用,但我喜欢的是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)

它可以将您的Custom对象转换为NSDictionary,反之亦然,即使它支持转换字典或数组或对象中的任何自定义对象(即组合)

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


0  

Define your custom class inherits from "AutoBindObject". Declare properties which has the same name with keys in NSDictionary. Then call method:

定义您的自定义类继承自“AutoBindObject”。声明与NSDictionary中的键具有相同名称的属性。然后调用方法:

[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

实际上,我们可以自定义类来将不同的属性名称映射到字典中的键。除此之外,我们可以绑定嵌套对象。请看一下这个演示。用法很简单:https://github.com/caohuuloc/AutoBindObject

#1


19  

Add a new initWithDictionary: method to Order:

在Order中添加一个新的initWithDictionary:方法:

- (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

不要忘记将initWithDictionary的签名添加到Order.h文件中

In the method where you get JSON:

在获得JSON的方法中:

NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSError *e;
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:jsonData options:nil error:&e];
Order *order = [[Order alloc] initWithDictionary:dict];

#2


11  

If the property names on your object match the keys in the JSON string you can do the following:

如果对象上的属性名称与JSON字符串中的键匹配,则可以执行以下操作:

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.

要将JSON字符串映射到Object,您需要先将字符串转换为NSDictionary,然后在NSObject上使用一个使用键值编码来设置每个属性的方法。

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.

如果键不匹配,则可以在对象类中覆盖NSObject的实例方法 - [NSObject valueForUndefinedKey:]。

To map you Object to JSON you can use the Objective-C runtime to do it automatically. The following works with any NSObject subclass:

要将Object映射到JSON,您可以使用Objective-C运行时自动执行此操作。以下适用于任何NSObject子类:

#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


4  

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


3  

this will be more convenient for you :

这对你来说会更方便:

 - (instancetype)initWithDictionary:(NSDictionary*)dictionary {
        if (self = [super init]) {
            [self setValuesForKeysWithDictionary:dictionary];}
        return self;
    }

#5


0  

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

完成此操作的最佳方法是使用库进行序列化/反序列化,许多库都可用,但我喜欢的是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)

它可以将您的Custom对象转换为NSDictionary,反之亦然,即使它支持转换字典或数组或对象中的任何自定义对象(即组合)

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


0  

Define your custom class inherits from "AutoBindObject". Declare properties which has the same name with keys in NSDictionary. Then call method:

定义您的自定义类继承自“AutoBindObject”。声明与NSDictionary中的键具有相同名称的属性。然后调用方法:

[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

实际上,我们可以自定义类来将不同的属性名称映射到字典中的键。除此之外,我们可以绑定嵌套对象。请看一下这个演示。用法很简单:https://github.com/caohuuloc/AutoBindObject