使用节标题和节行解析 JSON
Posted
技术标签:
【中文标题】使用节标题和节行解析 JSON【英文标题】:Parsing JSON with section headers and section rows 【发布时间】:2013-11-26 18:06:43 【问题描述】:我正在努力解决看起来应该很简单的事情。将以下 JSON 解析为 tableview,将类别名称作为部分标题以及搜索这些部分的详细信息。这是我的 JSON。如您所见,我有多个类别(例如婴儿和其他婴儿用品等),在这些类别下是我想要在每个类别下的详细信息。
"items":
"post":
"categories": [
[
"Baby",
"title": "trying with category id again",
"price": "3344.55",
"category_key": "3"
],
[
"Cars & Trucks",
"title": "putting in title",
"price": "3000.99",
"category_key": "7",
],
[
"Cars & Trucks",
"title": "adding another listing",
"price": "400000.99",
"category_key": "7"
],
这是我的代码。总的来说,我有 14 个类别。我下面的代码似乎解析了 JSON,它知道有 14 个类别,但值显示为 0、1、2、3 等(键),而不是 category_name 的实际值。
- (void)fetchedData:(NSData *)responseData
//parse out the json data
NSError* error;
NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
_tableData = [json objectForKey:@"items"][@"post"][@"category_name"];
_filteredItemArray = [_tableData valueForKey:@"category_name"];
dispatch_async(dispatch_get_main_queue(), ^
[m_tableView reloadData];
);
//_buyCategory = json[@"items"][@"post"];
NSLog(@"Items in Dictionary: %@", _filteredItemArray); /// I CAN SEE ALL MY DATA
NSLog(@"Array Count: %u", [_filteredItemArray count]); ///THE COUNT SHOWS 14
这是我的表格数据:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
return [[_filteredItemArray objectAtIndex:section] objectForKey:@"category_name"]; ///APP CRASHES HERE...BUT THIS SEEMS RIGHT TO ME
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
// Return the number of rows in the section.
return [[[[_tableData objectAtIndex:section] objectAtIndex:1] allKeys] count];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *CellIdentifier = @"Cell";
CustomBuyMainCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
NSDictionary* tempResults = [_tableData objectAtIndex:indexPath.row];
_buyTitle = [tempResults objectForKey:@"title"];
_buyPrice = [tempResults objectForKey:@"price"];
cell.buyMainTitle.text = _buyTitle;
cell.buyMainPrice.text = _buyPrice;
//NSLog(@"TempResults: %@", _buyTitle);
return cell;
#pragma mark - Segue
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
if ([[segue identifier] isEqualToString:@"showDetail"])
BuyDetail *buyDetail = [segue destinationViewController];
// In order to manipulate the destination view controller, another check on which table (search or normal) is displayed is needed
if(sender == self.searchDisplayController.searchResultsTableView)
//buyDetail.itemDetailArray = [self.tableData objectAtIndex:[m_tableView indexPathForSelectedRow].row];
else
//buyDetail.itemDetailArray = [self.tableData objectAtIndex:[m_tableView indexPathForSelectedRow].row];
我的 php:
$channel ['json']['categories'][$category_name][]['items'][] = array(
'ID' => $ID,
'title' => $title,
'price' => $price,
'date_time' => $date_time,
'description' => $description,
);
$channels = array($channel);
$json = json_encode($channel);
header('Content-type: application/json');
echo $json;
我认为我严重遗漏了一些东西,因此非常感谢任何帮助。
【问题讨论】:
您想将“Baby”和“Other Baby Stuff”作为部分标题的标题吗? 是的,但我现在有 14 个类别,这些类别将会增长。所以我不想在我的代码中指定类别名称。我只想解析出类别名称。这有意义吗? 检查我修改后的答案。希望这就足够了 在您的 JSON 中,您是否碰巧在"items": "post": "category_name":
下列出了一个名为 "category_name"
的类别?如果不是,我无法理解您的代码中的_filteredItemArray
不是nil
。
谢谢!对不起,什么是“结果”?和 tempDictionary ......你的意思是“temp”吗?它在这两个地方给了我错误。
【参考方案1】:
经过扩展讨论,您的 JSON 似乎已标准化,我们可以继续使用以下代码:
- (void)fetchedData:(NSData *)responseData
NSError *error;
//declare "NSDictionary *jsonDictionary;" in the .h of this class
//no need to make an array, simply use the response dictionary
jsonDictionary = [NSJSONSerialization JSONObjectWithData:responseData
options:kNilOptions
error:&error];
//get all keys (since there may be "holes" in the numbering)
//declare "NSArray *arrAllKeys;" in the .h of this class
arrAllKeys = [[jsonDictionary objectForKey:@"items"] allKeys];
[m_tableView reloadData];
//NOTE: No need for _tableData or _filteredItemArray objects
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
return [[jsonDictionary objectForKey:@"items"] count];
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
return [[[[jsonDictionary objectForKey:@"items"]
objectForKey:[arrAllKeys objectAtIndex:section]]
objectForKey:@"details"] count];
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
return [[[jsonDictionary objectForKey:@"items"]
objectForKey:[arrAllKeys objectAtIndex:section]]
objectForKey:@"categories"];
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *CellIdentifier = @"Cell";
CustomBuyMainCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[[NSBundle mainBundle] loadNibNamed:@"CustomBuyMainCell"
owner:self
options:nil]
objectAtIndex:0];
NSString *categoryItemName = [[[[[jsonDictionary objectForKey:@"items"]
objectForKey:[arrAllKeys objectAtIndex:indexPath.section]]
objectForKey:@"details"]
objectAtIndex:indexPath.row]
objectForKey:@"title"];
NSString *categoryItemPrice = [[[[[jsonDictionary objectForKey:@"items"]
objectForKey:[arrAllKeys objectAtIndex:indexPath.section]]
objectForKey:@"details"]
objectAtIndex:indexPath.row]
objectForKey:@"price"];
[cell.buyMainTitle setText:categoryItemName];
[cell.buyMainPrice setText:categoryItemPrice];
return cell;
//NOTE: No need for tempResults or _buyTitle or _buyPrice objects anymore
//(unless you are using _buyTitle & _buyPrice elsewhere as well)
-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
if ([[segue identifier] isEqualToString:@"showDetail"])
BuyDetail *buyDetail = [segue destinationViewController];
//declare and synthesize in the BuyDetail.h
//"@property (nonatomic, strong) NSDictionary *selectedCategoryItem;"
int mySelectedSection = [m_tableView indexPathForSelectedRow].section;
int mySelectedRowInSection = [m_tableView indexPathForSelectedRow].row;
buyDetail.selectedCategoryItem = [[[[jsonDictionary objectForKey:@"items"]
objectAtIndex:[arrAllKeys objectAtIndex:mySelectedSection]]
objectForKey:@"details"]
objectAtIndex:mySelectedRowInSection];
//NOTE: selectedCategoryItem is a dictionary object in your BuyDetail
//handle it like as you would handle any other dictionary
distance
的值是整数,所以我们需要这样获取它:
int distanceInMiles = [[[[[[[jsonDictionary objectForKey:@"items"]
objectForKey:[arrAllKeys objectAtIndex:indexPath.section]]
objectForKey:@"details"]
objectAtIndex:indexPath.row]
objectForKey:@"distance"]
objectForKey:@"miles"] intValue];
//assuming categoryItemDistance is NSString object
categoryItemDistance = [NSString stringWithFormat:@"%d",distanceInMiles];
【讨论】:
哦,如此接近!我只是在这里遇到错误:在@interface 上看不到 NSArray: if (cell == nil) cell = [[[NSBundle mainBundle] loadNibNamed:@"CustomBuyMainCell" owner:self options:nil] objectAtIndexPath:0]; @mreynol : 哦,又是屎...应该是cell = [[[NSBundle mainBundle] loadNibNamed:@"CustomBuyMainCell" owner:self options:nil] objectAtIndex:0];
...不是objectAtIndexPath:0
,应该是objectAtIndex:0
。原因:NSArray
没有提供任何名为-objectAtIndexPath:
的实例方法。它提供objectAtIndex:
。这只是我的几个错字之一:/。我的错,我会更新我的答案......
好的,清除了错误!但是当我现在运行时它崩溃了:(
-[__NSCFDictionary objectAtIndex:]:无法识别的选择器发送到实例 0x14597b60 2013-11-29 09:40:42.999 OnTradar[20438:60b] *** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:'-[__NSCFDictionary objectAtIndex:]:无法识别的选择器发送到实例 0x14597b60'
@mreynol : ohhhhhhh... 在items
中,您有“1”作为键的名称,然后它的值就是其余部分。同样,您有一个名为“2”的键,它是各自的值,依此类推。嗯......它看起来就像一个数组......但......不是。没有问题。让我们看看以上是关于使用节标题和节行解析 JSON的主要内容,如果未能解决你的问题,请参考以下文章
视频第2,3节 Spring Boot完美使用FastJson解析JSON数据
JSONObject 和 GSON 解析 JSON 数据详解(转)