Objective-C将json解析为对象列表

时间:2014-06-05 14:28:52

标签: ios objective-c json

我需要将一个json字符串解析为NSMutableArray ...我按如下方式执行:

    JsonString = "{
   "list":[
      {
         "IDI":{
            "IDI_ID":1
         },
         "PAR_VPARAM":"param1",
         "PAR_VALUE":"value1"
      },
      {
         "IDI":{
            "IDI_ID":2
         },
         "PAR_VPARAM":"param2",
         "PAR_VALUE":"value2"
      },
      {
         "IDI":{
            "IDI_ID":3
         },
         "PAR_VPARAM":"param3",
         "PAR_VVALUE":"value3"
      }
   ]
}";


NSData *data = [JsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&err];
NSMutableArray *resultArray = [json objectForKeyedSubscript:@"list"];

我有一个名为PARAMETERS的对象,它具有与JSON的单个项目相同的结构:“list”。当我解析它,它工作,问题是在json中每个项目内的对象:“IDI”,总是用空值解析。

for(NSObject *obj in resultArray){
     Parameters *paritem = (Parameters *)obj;
     int test = paritem.IDI.IDI_ID; //Error here!
}

我该怎么做?

2 个答案:

答案 0 :(得分:2)

NSJSONSerialization无法将您的JSON数据映射到自定义类。如果您指定了正确的NSJSONReadingOptions,它将提供NSStringNSNumberNSDictionaryNSArray个对象(或其可变对应对象)。

如果要将此数据映射到Parameters类,则必须自己提供该逻辑。你不能简单地投射NSDictionary

for(NSObject *obj in resultArray){
    Parameters *paritem = [[Parameters alloc] init];

    paritem.PAR_VPARAM = obj[@"PAR_VPARAM"];
    paritem.PAR_VALUE = obj[@"PAR_VALUE"];

    // To capture the IDI property, you will either have to
    // define a new IDI class with a property named "IDI_ID",
    // live with NSDictionary, or add an "IDI_ID" property
    // to your Parameters class.

    // In this example, I left the value as a dictionary.
    paritem.IDI = obj[@"IDI"];

    // Here's how you would get the IDI_ID:
    NSNumber *IDI_ID = paritem.IDI[@"IDI_ID"];
}

除此之外,还有一些不请自来的风格提示:

  • 对于Obj-C中的变量和属性,lowerCamelCase是常规的。而不是paritem.PAR_VPARAM,请使用parItem.parVParam(请注意I中的首都parItem)。
  • 您的班级名称应该有两个或三个字母"名称空间" (非常类似于NSStringUIViewCGPoint)。如果您不能用几个字母代表这个特定项目,请使用您公司名称的缩写。如果所有其他方法都失败了,请使用您的姓名缩写。
  • 您的参数名称非常模糊,有些多余。每个属性是否真的需要以PAR_为前缀?您真的需要IDI_ID嵌套在IDI对象的Parameters属性中吗?您可以通过更简洁的方式使代码更具可读性。

如果你接受了这个建议,我的代码会是什么样子(我对你的源数据做了一些假设):

for(NSObject *obj in resultArray){
    APParameters *parItem = [[APParameters alloc] init];

    parItem.parameterName = obj[@"PAR_VPARAM"];
    parItem.parameterValue = obj[@"PAR_VALUE"];

    // To capture the IDI property, you will either have to
    // define a new IDI class with a property named "IDI_ID",
    // live with NSDictionary, or add a property to your
    // Parameters class which holds the IDI_ID value directly.

    // In this example, I grabbed the IDI_ID value directly.
    parItem.itemID = obj[@"IDI"][@"IDI_ID"];
}

答案 1 :(得分:0)

首先,如果您不打算添加或删除新对象,我建议您将JSON数据投放到NSArray而不是NSMutableArray到阵列。

关于"IDI"个索引,它们不像其他索引一样被解析为字符串,因为它们是字典。您还应手动创建Parameters对象,而不是直接转换。

一个例子:

// In Parameters.h
@property (nonatomic, strong) NSString *PAR_VPARAM;
@property (nonatomic, strong) NSDictionary *IDI;

然后解析JSON后,

for (NSDictionary *obj in resultArray){
     Parameters *paritem = [[Parameters alloc] init];
     paritem.PAR_VPARAM = [obj valueForKey:@"PAR_VPARAM"];
     paritem.IDI = [obj valueForKey:@"IDI"];
     int test = (int)[paritem.IDI valueForKey:@"IDI_ID"];
}

这应该可以正常工作,您可以为其他JSON索引创建新属性。