【问题标题】:How to convert NSDictionary to custom object如何将 NSDictionary 转换为自定义对象
【发布时间】:2014-02-15 06:39:12
【问题描述】:

我有一个 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;
}

在字符串中是:

{
  "Title" : "test",
  "Weight" : "32",
  "OrderId" : "55"
}

我得到带有代码的字符串 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];

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

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

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

【问题讨论】:

    标签: ios objective-c json nsdictionary nsjsonserialization


    【解决方案1】:

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

    [customObject loadFromDictionary:dic];
    

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

    【讨论】:

      【解决方案2】:

      这对你来说会更方便:

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

      【讨论】:

        【解决方案3】:

        假设你的属性名和字典键相同,你可以使用这个函数来转换任何对象

        - (void) setObject:(id) object ValuesFromDictionary:(NSDictionary *) dictionary
        {
            for (NSString *fieldName in dictionary) {
                [object setValue:[dictionary objectForKey:fieldName] forKey:fieldName];
            }
        }
        

        【讨论】:

        • 如果缺少任何字段,这将崩溃
        • 这应该会有所帮助。在设置值之前检查对象的 fieldName。 if ([object respondsToSelector:NSSelectorFromString(fieldName)]) { [object setValue:[dictionary objectForKey:fieldName] forKey:fieldName]; } } }
        【解决方案4】:

        做到这一点的完美方法是使用用于序列化/反序列化的库 有很多图书馆可用,但我喜欢的一个是 JagPropertyConverter https://github.com/jagill/JAGPropertyConverter

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

        【讨论】:

          【解决方案5】:

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

          要将 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];
          

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

          要将您的 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];
          }
          

          【讨论】:

            【解决方案6】:

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

            - (instancetype)initWithDictionary:(NSDictionary*)dictionary {
                if (self = [super init]) {
                    self.OrderId = dictionary[@"OrderId"];
                    self.Title = dictionary[@"Title"];
                    self.Weight = dictionary[@"Weight"];    
                }
                return self;    
            }
            

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

            在获取 JSON 的方法中:

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

            【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2023-04-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-01-15
            • 2011-11-28
            • 2014-04-17
            • 2018-05-08
            相关资源
            最近更新 更多