在 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 并将值添加到对象数组的主要内容,如果未能解决你的问题,请参考以下文章
jq json根据条件从内部数组中检索值并将其添加到数组之外
如何从嵌套 Json 数组角度 2 打印和分离键和值并将其添加到选择框中