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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21329793/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 23:14:43  来源:igfitidea点击:

How to convert NSDictionary to custom object

iosobjective-cjsonnsdictionarynsjsonserialization

提问by 1110

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。我应该怎么做才能从这本字典中获取对象?

回答by Andrey Gordeev

Add a new initWithDictionary:method to Order:

添加一个新initWithDictionary:方法到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.hfile

不要忘记将initWithDictionary's 签名添加到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];

回答by Gianluca Tranchedone

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 字符串映射到您的对象,您需要先将字符串转换为 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 valueForUndefinedKey:]对象类中 NSObject 的实例方法。

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

回答by shudima

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

回答by Hamsing Lee

this will be more convenient for you :

这对你来说会更方便:

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

回答by Cao Huu Loc

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

回答by M.Shuaib Imran

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)

它可以将您的自定义对象转换为 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];