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

Ios Objective-C将json解析为对象列表,ios,objective-c,json,Ios,Objective C,Json,我需要将json字符串解析为NSMutableArray。。。我是这样做的: JsonString = "{ "list":[ { "IDI":{ "IDI_ID":1 }, "PAR_VPARAM":"param1", "PAR_VALUE":"value1" }, { "IDI":{ "IDI_ID":2

我需要将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!
}

我该怎么做?

首先,如果您不打算向数组添加或删除新对象,我建议您将
JSON
数据转换为
NSArray
,而不是
NSMutableArray

关于
“IDI”
索引,它们不像其他索引那样被解析为字符串,因为它们是字典。您还应该手动创建
参数
对象,而不是直接强制转换

例如:

// 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索引创建新属性。

NSJSONSerialization不会将JSON数据映射到自定义类。它将提供
NSString
NSNumber
NSDictionary
NSArray
对象(或它们的可变对应项,如果您指定了右侧)

如果要将此数据映射到
参数
类,则必须自己提供该逻辑。您不能简单地强制转换
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.parVParam
    代替
    paritem.parVParam
    (注意
    paritem
    中的大写字母
    I
  • 您的类名应该有两个或三个字母的“名称空间”(很像
    NSString
    UIView
    CGPoint
    )。如果你想不出几个字母来代表这个特定的项目,请使用公司名称的缩写。如果其他方法都失败了,请使用您的姓名首字母
  • 您的参数名称非常模糊,而且有些冗余。每个属性是否真的需要加前缀
    PAR_uu
    ?您真的需要
    IDI_ID
    嵌套在
    Parameters
    对象的
    IDI
    属性中吗?通过更加简洁,您可以使代码更具可读性
下面是如果您接受了这个建议,您的代码可能会是什么样子(我对您的源数据做了一些假设):


如果需要可变数组,请使用选项NSJSONReadingMutableContainers。我发现从JSON创建新对象的最佳方法是为接受JSON字典的类编写
initWithDictionary
方法。@HotLicks我个人喜欢创建一个类方法,如
+[apThingWithDictionary:
,但事实上是一样的(尤其是弧)。是的,它们几乎是等价的。特别是如果您有创建嵌套对象的嵌套字典,那么这样做是很自然的,这样您就有了标准化的机制和样式。为您提供Jackson-ish实现的好处,但无需插入神秘的标记或编写神秘的规则。谢谢!关于代码,我只是使用了一个互联网的json示例。
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"];
}