UITableView 的 JSON 数据仍然为空

Posted

技术标签:

【中文标题】UITableView 的 JSON 数据仍然为空【英文标题】:JSON-data to UITableView is still empty 【发布时间】:2014-04-26 08:37:13 【问题描述】:

我已经从我的网站加载 JSON 数据并将其添加到 UITableView 但表格仍然是空的。应用程序没有崩溃,所以我真的不知道出了什么问题,也许你们中的某个人可以帮助我。我会给你下面的代码以及FilesOwner的连接。

提前致谢

我的 JSON 数据文件:

[
 name: "XYZ", details: "XYZ",
 name: "XYZ", details: "XYZ"
]

ViewController.h:

 #import <UIKit/UIKit.h>

@interface ViewController : UIViewController<UITableViewDelegate,UITableViewDataSource>

    IBOutlet UITableView *tableData;


@end

ViewController.m:

 #import "ViewController.h"

@interface ViewController ()
    NSMutableArray *myObject;
    NSDictionary *data;
    NSString *name;
    NSString *details;


@end

@implementation ViewController

- (void)viewDidLoad

    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    name = @"name";
    details = @"details";

    myObject = [[NSMutableArray alloc] init];

    NSURL *url = [NSURL URLWithString:@"http://example.com/JSON/index.php"];
    NSData *jsonSource = [NSData dataWithContentsOfURL:url];

    id jsonObjects = [NSJSONSerialization JSONObjectWithData:jsonSource options:NSJSONReadingMutableContainers error:nil];
    for (NSDictionary *dataDict in jsonObjects) 
        NSString *name_data = [dataDict objectForKey:@"name"];
        NSString *details_data = [dataDict objectForKey:@"details"];

        data = [NSDictionary dictionaryWithObjectsAndKeys:
                      name_data,name,
                      details_data,details,
                nil];
        [myObject addObject:data];
    


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    return myObject.count;


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    static NSString *CellIdentifier = @"Item";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) 
        cell=[[UITableViewCell alloc]initWithStyle:
              UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    


    NSDictionary *tmpDict = [myObject objectAtIndex:indexPath.row];

    NSMutableString *title;
    //text = [NSString stringWithFormat:@"%@",[tmpDict objectForKey:title]];
    title = [NSMutableString stringWithFormat:@"%@",
            [tmpDict objectForKeyedSubscript:name]];

    NSMutableString *second;
    second = [NSMutableString stringWithFormat:@"%@",
              [tmpDict objectForKey:details]];


    cell.textLabel.text = title;
    cell.detailTextLabel.text= second;


    return cell;



- (void)didReceiveMemoryWarning

    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.


@end

Main.storyboard:

Prototypecell 的 Reuse Identifier 是“Item”。

dataSource 连接到 ViewController delegate 连接到 ViewController tableData 连接到 ViewController

这就是我所做的一切...... 非常感谢:)

【问题讨论】:

在解析结束时,在 TableView 上尝试 reloadData 我在UITableViewCell方法的末尾添加了[tableView reloadData];,没有任何反应.. 为什么不直接使用jsonObjects 而放弃myObject,因为从技术上讲,myObjectjsonObjects 没有什么不同。另外...为什么要使用objectForKeyedSubscript,我建议改用objectForKey? (不确定,但这些建议可能无法真正帮助您解决核心问题,但至少会有所改进 还...jsonSource 的内容有效吗?在-viewDidLoad 的末尾设置一个断点并检查jsonSourcemyObject 看起来是否像您期望的那样 ViewDidLoad 的末尾myObject 中有0 个对象......所以一定有解析失败,如果我是对的?我之前也想过objective-c可能无法正确读取php文件,但是我没有找到像商业API一样命名它的解决方案.. 【参考方案1】:

viewDidLoad

- (void)viewDidLoad

    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    NSURL *url = [NSURL URLWithString:@"http://example.com/JSON/index.php"];
    NSData *jsonSource = [NSData dataWithContentsOfURL:url];

    //store the JSON into an array
    myObject = [[NSMutableArray alloc] init];
    myObject = [NSJSONSerialization JSONObjectWithData:jsonSource 
                                options:NSJSONReadingMutableContainers error:nil];
    [self.tableView reloadData];

numberOfSectionsInTableView

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView

    return 1;

numberOfRowsInSection

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    return myObject.count;

cellForRowAtIndexPath

- (UITableViewCell *)tableView:(UITableView *)tableView 
                                cellForRowAtIndexPath:(NSIndexPath *)indexPath
    static NSString *CellIdentifier = @"Item";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) 
        cell=[[UITableViewCell alloc]initWithStyle:
              UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    

    NSDictionary * obj = myObject[indexPath.row];
    cell.textLabel.text = obj[@"name"] ;
    cell.detailTextLabel.text= obj[@"details"] ;

    return cell;

【讨论】:

我测试了您的解决方案,表格仍然是空的,但感谢您的想法 好的,回来工作吧,我现在正在使用不同的 json php 脚本,它的工作原理!如果它直接与我的代码一起工作,但您的代码正在工作,我还没有测试过它。所以我必须非常感谢 :) 你做得很好。 @Criska nice,祝你的应用好运;-) @meda :Criska 的问题是问题 cmets 中指出的无效 json。你所建议的只是一种更有效的做事方式,但不会解决他的问题,因为myObject 将一直保持nil 直到 json 被修复( ...所有这些都在 cmets 中指出)在发布答案之前,我只是在等待确定 OP 的核心问题。【参考方案2】:

您的 json 响应中缺少键名的引号。

[
  
    "name": "XYZ",
    "details": "XYZ"
  ,
  
    "name": "XYZ",
    "details": "XYZ"
  
]

另外,为了改进,直接使用jsonObjects目前你正在阅读jsonObjects并制作myObject,这与jsonObjects本身没有什么不同

而且...由于您使用的是原型单元,因此您当前在-cellForRowAtIndexPath: 中的处理方式是错误的。即: 目前,你有一个if (cell == nil) 块......它是无用的(带有原型单元),你最终只会看到cell.textLabel.text

正确方法:

    转到故事板 选择原型细胞 (通过右侧的 Interface Builder)将其样式从 custom 更改为 subtitle

终于...

例子:

- (void)viewDidLoad

    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    NSURL *url = [NSURL URLWithString:@"http://example.com/JSON/index.php"];
    NSData *jsonSource = [NSData dataWithContentsOfURL:url];

    //declare NSArray *jsonObjects; in the .h
    jsonObjects = [NSJSONSerialization JSONObjectWithData:jsonSource 
                                                  options:NSJSONReadingMutableContainers 
                                                    error:nil];


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

    static NSString *CellIdentifier = @"Item";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    //useless when using a prototype cell
    //if (cell == nil) 
    //    cell=[[UITableViewCell alloc]initWithStyle: UITableViewCellStyleSubtitle 
    //                               reuseIdentifier:CellIdentifier];
    //

    //fyi: old style
    //NSString *strName = [[jsonObjects objectAtIndex:indexPath.row] objectForKey:@"name"];
    //NSString *strDetails = [[jsonObjects objectAtIndex:indexPath.row] objectForKey:@"details"];

    //new style (but doesn't matter which one you adopt)
    NSString *strName = jsonObjects[indexPath.row][@"name"];
    NSString *strDetails = jsonObjects[indexPath.row][@"details"];

    [cell.textLabel setText:strName];
    [cell.detailTextLabel setText:strDetails];

    return cell;


仅供参考:主要是 json 无效。 如果您的 json 格式正确,您的原始代码会起作用,但原型单元肯定需要正确修复。

【讨论】:

以上是关于UITableView 的 JSON 数据仍然为空的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中将 JSON 加载到 UItableView

UITableView 不使用 SwiftyJSON 和 Alamofire 加载数据

Swift3:如果为空则隐藏 UITableView

UITableView dataSource 对象在滚动时变为空

在 UITableView 中显示 JSON 数据

使用 JSON 数据填充 UITableView