在 iOS 中解析 json 并将值添加到对象数组

Posted

技术标签:

【中文标题】在 iOS 中解析 json 并将值添加到对象数组【英文标题】:Parsing json in iOS and adding values to an array of objects 【发布时间】:2014-03-12 17:42:34 【问题描述】:

我有以下 json 文件,我正在尝试从我的 ios 应用程序中解析它。我定义了一个解析文件的方法,但我不知道如何处理整数,即 ID。我想将数据放在一个数组(促销)中,其中包含一个标题和一个产品数组(下面解释得更好)。有什么建议或好的参考吗?

Json 文件:

 "promotions": 
    "1": 
        "title": "promotion title",
        "product": 
            "1": 
                "title": "product title",
                "description": "this is the description"
            ,
            "2": 
                "title": "product title",
                "description": "this is the description"
            
          
      ,
    "2":  "3": 
                "title": "product title",
                "description": "this is the description"
            ,
            "4": 
                "title": "product title",
                "description": "this is the description"
            
         
       
   

这些是我的数据类:

Promotion  NSString *title; NSArray *products;
Product  NSString *title; NSString *description;

我的函数加载 json 并将所有对象添加到促销数组中,对于每个促销,促销数组包含一个产品数组。

- (NSArray *) infoFromJSON
    NSURL *url=[NSURL URLWithString:urlJSON];

    NSURLRequest *request = [NSURLRequest requestWithURL:url
                                             cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
                                         timeoutInterval:30.0];
    NSURLResponse *response;
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];

    NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];

    NSMutableArray *promotions = [[NSMutableArray alloc] init];

    NSArray *array = [jsonDictionary objectForKey:@"promotions"];
    NSLog(@"array: %@", array);
    NSLog(@"items en array %d", [array count]);
    NSLog(@"object 1 en array: %@", [array objectAtIndex:1]);

    // Iterate through the array of dictionaries
    for(NSDictionary *dict in array) 
        Promotion *promotion= [[Promotion alloc] initWithJSONDictionary:dict];
        // Add the promotion object to the array
        [promotions  addObject:promotions];

        //Add the products to each promotion??
    

    // Return the array of promotion objects
    return promotions;


【问题讨论】:

首先(这不是挑剔)不是 JSON 文件。您省略了 VERY CRITICAL 前导 (可能还有尾随 - 我没有数过)。 JSON 文件中的每个字符都是有意义的,您必须学习如何正确阅读它们。 至于 JSON 本身,它很丑,而且可能是由不太了解 JSON 的人制作的。可能最简单的处理方法(如果无法纠正)是将每个“对象”(NSDictionary)的元素复制到相应的数组中——相对简单。 我忘记复制前导 和尾随 但 json 文件是正确的,我使用在线 json 验证器进行了验证。 什么是“促销”?我在 JSON 中没有看到。 【参考方案1】:

你的 JSON 没有很好的定义,你必须尝试使用​​类似的东西:

["promotion_id": 1
  "title": "promotion title", 
  "products": ["product_id": 1, 
                "title": "product title", 
                "description": "this is the description"
               ,
               "product_id": 2, 
                "title": "product title", 
                "description": "this is the description"
               ,
               ...
              ]
 ,
 "promotion_id": 2
  "title": "promotion title", 
  "products": ["product_id": 3, 
                "title": "product title", 
                "description": "this is the description"
               ,
               "product_id": 4, 
                "title": "product title", 
                "description": "this is the description"
               ,
               ...
              ]
 ,
 ...
]

然后,要将 JSON 字典解析为自定义对象,我建议您使用类别 NSObject+Motis 我最近一直在工作。将 JSON 字典映射到您的自定义 Objective-C 对象非常有用。

主要是你必须做的:

@interface Promotion : NSObject
@property (nonatomic, assing) NSInteger promotionId; 
@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) NSArray *products;
@end

@implementation Promotion
- (NSDictionary*)mjz_motisMapping

    return @@"promotion_id" : @"promotionId",
             @"title" : @"title",
             @"products" : @"products",
            ;


- (NSDictionary*)mjz_arrayClassTypeMappingForAutomaticValidation

    return @"products": [Product class];


@end

@interface Product : NSObject
@property (nonatomic, assing) NSInteger productId; 
@property (nonatomic, strong) NSString *title;
@property (nonatomic, strong) NSArray *productDescription;
@end

@implementation Promotion
- (NSDictionary*)mjz_motisMapping

    return @@"product_id" : @"productId",
             @"title" : @"title",
             @"description" : @"productDescription",
            ;

@end

然后执行解析:

- (void)parseTest

    NSData *data = jsonData; // <-- YOUR JSON data 

    // Converting JSON data into array of dictionaries.
    NSError *error = nil;
    NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];

    if (error)
        return; // <--- If error abort.

    NSMutableArray *promotions = [NSMutableArray array];
    for (NSDictionary *dict in jsonArray)
    
        Promotion *promotion = [[Promotion alloc] init];
        [promotion mjz_setValuesForKeysWithDictionary:dict];
        [promotions addObject:promotion];
    

您可以在这篇文章中了解它的工作原理:http://blog.mobilejazz.cat/ios-using-kvc-to-parse-json

希望它能帮助你,就像它帮助了我一样。

【讨论】:

【参考方案2】:

那是讨厌的 JSON。可以的话,换一个。目前你有许多字典,字典中的键是数字。这些字典应该是数组。

您已将代码编写为数组。

如果您需要保留 JSON,请读出字典然后迭代键,或者,如果可以(因为您没有使用键进行排序),只需从字典中获取所有值作为数组并对其进行迭代。

理想情况下,更改 JSON 并使用 RestKit...

【讨论】:

当您说更改 json 时,您的意思是仅删除 ID 吗?我可以尝试询问他们是否可以更改 json,但最简单快速的解决方案是尝试在不更改 json 的情况下解析它。 然后在促销字典上使用allValues。我越看 JSON 越糟糕,你真的应该改变它...... 没有。他的意思是与设计 JSON 输出的人交谈,告诉他们一些在 *** 上很聪明的人正在摇头,对他们生成的 JSON 表示怀疑,并请他们改一下。 我无法更改 JSON,您能否举个例子说明如何解析 allValues 并在我的数组中添加每个字符串?【参考方案3】:

我终于把 json 改成了:


    "promotions": [
        
            "id": "1",
            "title": "promotion title",
            "products": [
                
                    "id": "1",
                    "title": "product title",
                    "description": "description"
                ,
                
                    "id": "2",
                    "title": "product title",
                    "description": "description"
                
            ]
        ,
        
            "id": "2",
            "title": "promotion title",
            "products": [
                
                    "id": "6",
                    "title": "product title",
                    "description": "description"
                
            ]
        
    ]

这就是我解析 json 的方式:

- (NSArray *) infoFromJSON
    // Create a NSURLRequest with the given URL
    NSURL *url=[NSURL URLWithString:urlJSON];

    NSURLRequest *request = [NSURLRequest requestWithURL:url
                                             cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
                                         timeoutInterval:30.0];
    // Get the data
    NSURLResponse *response;
    NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];

    //Create an array to hold all the information
    NSMutableArray *info = [[NSMutableArray alloc] init];

    // Now create a NSDictionary from the JSON data
    NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];

    NSArray *arrayPromotions = [jsonDictionary objectForKey:@"promotions"];

    for(NSDictionary *dictCategories in arrayPromotions) 
        Block *promotion = [[Block alloc] initWithJSONDictionary:dictCategories];

        NSArray *arrayProducts = [dictCategories objectForKey:@"products"];

        promotion.questions = [[NSMutableArray alloc] init];
        for(NSDictionary *dictProducts in arrayProducts) 
            Product *product = [[Product alloc] initWithJSONDictionary:dictProducts];
            NSLog(@"product title %@", product.title);
            [promotions.product addObject:product];
        

        [info addObject:promotion];
        NSLog(@"Promotion: %@ product 2: %@", promotion.title, [[promotion.products objectAtIndex:1] title]);
    

    // Return the array of Location objects
    return info;


我在两个数据类(Promotion 和 Product)中定义并实现了方法 initWithJSONDictionary

- (id)initWithJSONDictionary:(NSDictionary *)jsonDictionary     
    if(self = [self init]) 
        self.title = [jsonDictionary objectForKey:@"title"];
    
    return self;

【讨论】:

以上是关于在 iOS 中解析 json 并将值添加到对象数组的主要内容,如果未能解决你的问题,请参考以下文章

iOS解析内部Json

jq json根据条件从内部数组中检索值并将其添加到数组之外

怎么将json对象添加进json数组中

如何从嵌套 Json 数组角度 2 打印和分离键和值并将其添加到选择框中

iPhone JSON框架不解析不在对象或数组内的JSON字符串对象

Swift 和 JSON 只解析一个对象而不是一个数组