使用 Objective-C 到 UITableView 的 JSON 数据

Posted

技术标签:

【中文标题】使用 Objective-C 到 UITableView 的 JSON 数据【英文标题】:JSON data to UITableView using Objective-C 【发布时间】:2015-09-21 10:41:40 【问题描述】:

-- 主 JSON 文件的更新问题 --

我正在尝试将名称添加到表格视图中。但桌子总是空的。 (Xcode 7.1b1,ios 9.1b2) 这只是我正在测试我的代码的示例 .json 文件。主 json 文件有更多的数据。

我成功地添加了示例 json 文件中的数据。但是现在使用主json文件后,表又是空的了。

.json 文件

[
  
    "150978": 
      "jobs": 
        "D0-C14008-CW": 
          "05-9032": 
            "G-05": 
              "hours_rwk": "False",
              "hours_st": "4L",
              "hours_ewo_id": "D0-C14008-CWddda",
              "hours_ewo": "True",
              "hours_dt": "0L",
              "hours_ot": "0L",
              "comments": ""
            
          ,
          "05-9031": 
            "B-02": 
              "hours_rwk": "False",
              "hours_st": "4L",
              "hours_ewo_id": "",
              "hours_ewo": "False",
              "hours_dt": "0L",
              "hours_ot": "0L",
              "comments": ""
            
          
        
      ,
      "name": "CirilloBetancourt",
      "site_id": "D0-C14008-CW",
      "trade": "Carpenter",
      "note": "",
      "signed_in": "True",
      "time_in": "08: 30",
      "time_out": "16: 30",
      "signed_out": "True"
    ,
    "151243": 
      "jobs": ,
      "name": "JasonDiaz",
      "site_id": "D0-C14008-CW",
      "trade": "Carpenter",
      "note": "nowork",
      "signed_in": "False",
      "time_in": "06: 00",
      "time_out": "06: 00",
      "signed_out": "False"
    ,
    "151248": 
      "jobs": ,
      "name": "AngelTorresMadrigal",
      "site_id": "D0-C14008-CW",
      "trade": "Carpenter",
      "note": "nowork",
      "signed_in": "False",
      "time_in": "06: 00",
      "time_out": "06: 00",
      "signed_out": "False"
    ,
    "151336": 
      "jobs": ,
      "name": "DanielFrey",
      "site_id": "D0-C14008-CW",
      "trade": "Carpenter",
      "note": "nowork",
      "signed_in": "False",
      "time_in": "06: 00",
      "time_out": "06: 00",
      "signed_out": "False"
    ,
    "151419": 
      "jobs": 
        "D0-C14009-CW1": 
          "05-9033": 
            "G-07": 
              "hours_rwk": "False",
              "hours_st": "8L",
              "hours_ewo_id": "0",
              "hours_ewo": "False",
              "hours_dt": "0L",
              "hours_ot": "0L",
              "comments": ""
            
          
        ,
        "D0-C14008-CW": 
          "05-9031": 
            "B-02": 
              "hours_rwk": "False",
              "hours_st": "0L",
              "hours_ewo_id": "0",
              "hours_ewo": "True",
              "hours_dt": "0L",
              "hours_ot": "2L",
              "comments": ""
            
          
        
      ,
      "name": "MikeGullan",
      "site_id": "D0-C14008-CW",
      "trade": "Carpenter",
      "note": "",
      "signed_in": "False",
      "time_in": "06: 00",
      "time_out": "06: 00",
      "signed_out": "False"
    ,
    "9990666": 
      "jobs": ,
      "name": "MattStaricha",
      "site_id": "D0-C14008-CW",
      "trade": "Carpenter",
      "note": "nowork",
      "signed_in": "False",
      "time_in": "06: 00",
      "time_out": "06: 00",
      "signed_out": "False"
    ,
    "9992610": 
      "jobs": ,
      "name": "MatthewBigelow",
      "site_id": "D0-C14008-CW",
      "trade": "Carpenter",
      "note": "nowork",
      "signed_in": "False",
      "time_in": "06: 00",
      "time_out": "06: 00",
      "signed_out": "False"
    ,
    "9992778": 
      "jobs": ,
      "name": "ZhouTan",
      "site_id": "D0-C14008-CW",
      "trade": "Carpenter",
      "note": "nowork",
      "signed_in": "False",
      "time_in": "06: 00",
      "time_out": "06: 00",
      "signed_out": "False"
    ,
    "9993273": 
      "jobs": ,
      "name": "RandyFarinelli",
      "site_id": "D0-C14008-CW",
      "trade": "Carpenter",
      "note": "nowork",
      "signed_in": "False",
      "time_in": "06: 00",
      "time_out": "06: 00",
      "signed_out": "False"
    ,
    "9996467": 
      "jobs": ,
      "name": "AlvaroSandoval(Guardado)",
      "site_id": "D0-C14008-CW",
      "trade": "Mason",
      "note": "nowork",
      "signed_in": "False",
      "time_in": "06: 00",
      "time_out": "06: 00",
      "signed_out": "False"
    ,
    "9996763": 
      "jobs": ,
      "name": "JesusZarate",
      "site_id": "D0-C14008-CW",
      "trade": "Mason",
      "note": "nowork",
      "signed_in": "False",
      "time_in": "06: 00",
      "time_out": "06: 00",
      "signed_out": "False"
    ,
    "9996767": 
      "jobs": ,
      "name": "JorgeRomero",
      "site_id": "D0-C14008-CW",
      "trade": "Mason",
      "note": "nowork",
      "signed_in": "False",
      "time_in": "06: 00",
      "time_out": "06: 00",
      "signed_out": "False"
    ,
    "9996768": 
      "jobs": 
        "D0-C14008-CW": 
          "05-9032": 
            "G-05": 
              "hours_rwk": "False",
              "hours_st": "3L",
              "hours_ewo_id": "0",
              "hours_ewo": "False",
              "hours_dt": "0L",
              "hours_ot": "0L",
              "comments": ""
            
          ,
          "05-9031": 
            "B-02": 
              "hours_rwk": "False",
              "hours_st": "5L",
              "hours_ewo_id": "0",
              "hours_ewo": "False",
              "hours_dt": "0L",
              "hours_ot": "0L",
              "comments": ""
            
          
        
      ,
      "name": "VictorRuiz",
      "site_id": "D0-C14008-CW",
      "trade": "Mason",
      "note": "",
      "signed_in": "False",
      "time_in": "06: 00",
      "time_out": "06: 00",
      "signed_out": "False"
    ,
    "9996771": 
      "jobs": ,
      "name": "GabinoMata-Neri",
      "site_id": "D0-C14008-CW",
      "trade": "Mason",
      "note": "nowork",
      "signed_in": "False",
      "time_in": "06: 00",
      "time_out": "06: 00",
      "signed_out": "False"
    ,
    "9999247": 
      "jobs": 
        "D0-C14008-CW": 
          "05-9032": 
            "G-05": 
              "hours_rwk": "False",
              "hours_st": "8L",
              "hours_ewo_id": "0",
              "hours_ewo": "False",
              "hours_dt": "0L",
              "hours_ot": "0L",
              "comments": ""
            
          ,
          "05-9031": 
            "B-02": 
              "hours_rwk": "True",
              "hours_st": "0L",
              "hours_ewo_id": "0",
              "hours_ewo": "False",
              "hours_dt": "0L",
              "hours_ot": "1L",
              "comments": ""
            
          
        
      ,
      "name": "FranciscoMontez",
      "site_id": "D0-C14008-CW",
      "trade": "Mason",
      "note": "",
      "signed_in": "False",
      "time_in": "06: 00",
      "time_out": "06: 00",
      "signed_out": "False"
    ,
    "9999314": 
      "jobs": ,
      "name": "RomanHernandez",
      "site_id": "D0-C14008-CW",
      "trade": "Mason",
      "note": "nowork",
      "signed_in": "False",
      "time_in": "06: 00",
      "time_out": "06: 00",
      "signed_out": "False"
    
  
]

.h 文件

#import <UIKit/UIKit.h>

@interface TableViewController : UITableViewController

@property (nonatomic, strong) NSArray *nameArray;
@property (nonatomic, strong) NSArray *dict;
@property (nonatomic, strong) NSData *data;
@property (nonatomic, strong) NSString *filePath;

@end

.m 文件

#import "TableViewController.h"
#import "TableViewCell.h"

@interface TableViewController ()

@end

@implementation TableViewController

- (void)viewDidLoad 
    [super viewDidLoad];

    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;

    NSError *error = nil;

    _filePath = [[NSBundle mainBundle] pathForResource:@"data" ofType:@"json"];
    _data = [NSData dataWithContentsOfFile:_filePath];
    _dict = [NSJSONSerialization JSONObjectWithData:_data options:0 error:&error];



- (void)didReceiveMemoryWarning 
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.


#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
//#warning Incomplete implementation, return the number of sections
    return 1;


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
//#warning Incomplete implementation, return the number of rows
    return _dict.count;


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TableCell" forIndexPath:indexPath];

    // Configure the cell...
    NSDictionary *dict = _dict[indexPath.row];
NSString *name = dict[@"name"];
cell.titleLabel.text = name;

    return cell;

【问题讨论】:

请分享主JSON文件从开始到一些元素 _nameArray中,你得到了多少计数,你得到了什么结果 【参考方案1】:

您的 JSON 实际上格式错误。应该是:

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

当您执行_dict = [NSJSONSerialization JSONObjectWithData:_data options:0 error:&amp;error]; 时,您实际得到的是一个字典数组,而不是单个字典。所以调用_nameArray = [_dict objectForKey:@"name"];实际上应该返回nil或者崩溃。

你的实现应该是这样的:

#import "TableViewController.h"
#import "TableViewCell.h"

@interface TableViewController ()

@end

@implementation TableViewController

- (void)viewDidLoad 
    [super viewDidLoad];
    NSError *error = nil;
    _filePath = [[NSBundle mainBundle] pathForResource:@"data" ofType:@"json"];
    _data = [NSData dataWithContentsOfFile:_filePath];
    // Remember here, __dict is an array, I kept the same name as your code but it is NOT a dictionary.
    _dict = [NSJSONSerialization JSONObjectWithData:_data options:0 error:&error];
    _nameArray = [_dict objectForKey:@"name"];


#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
    return 1;


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


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TableCell" forIndexPath:indexPath];
    // Remember here, __dict is an array, I kept the same name as your code but it is NOT a dictionary.
    NSDictionary *dict = _dict[indexPath.row];
    NSString *name = dict[@"name"];
    cell.titleLabel.text = name;
    return cell;

【讨论】:

我将 .h 文件中的 dict 从 NSDictionary 更改为 NSArray,对我的代码进行了必要的更改,但表仍然是空的! 你连接控制器作为表视图数据源和委托了吗? 我用主 json 文件更新了帖子。你能明白为什么数据现在没有显示吗? @iFlames 问题在于 JSON 的顶部容器是一个数组,其中包含所有值的巨大字典。这意味着您的表视图必须处理作为字典而不是数组的数据源。基本上,顶部的数组容器在某种程度上是无用的,你需要忽略它,只处理它里面的字典。【参考方案2】:

key "name" 不会返回一个数组。它将返回 NSString

【讨论】:

【参考方案3】:

您的 JSON 似乎是字典数组。所以这就是你解决问题的方法:

从JSON解析数据时,保存在NSArray

@property (nonatomic, strong) NSArray *jsonArray;
self.jsonArray = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; 

然后在读取单元格中的数据时,像这样读取它:

NSDictionary *nameDict = self.jsonArray[0];
NSLog(@"Name = %@", nameDict[@"name"]); // This prints Name = XYZ

【讨论】:

【参考方案4】:

.json文件的实际格式应该是这样的:

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

现在您的 .m 文件应如下所示:

NSError *error = nil;

_filePath = [[NSBundle mainBundle] pathForResource:@"data" ofType:@"json"];
_data = [NSData dataWithContentsOfFile:_filePath];
_dataArray = [NSJSONSerialization JSONObjectWithData:_data options:0 error:&error];


//_nameArray = [_dict objectForKey:@"name"];



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


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TableCell" forIndexPath:indexPath];

    NSDictionary *dict = [self.nameArray objectAtIndex:indexPath.row];
    cell.titleLabel.text = dict[@“name”];


    return cell;

希望这会有所帮助。

【讨论】:

【参考方案5】:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TableCell" forIndexPath:indexPath];

    // Configure the cell...
        NSString *name = [self.nameArray objectAtIndex:indexPath.row];
        cell.titleLabel.text = name;


    //NSString *desc = [self.results objectForKey:@""];

    return cell;

【讨论】:

嘿@iFlames 检查我的答案,只需替换下面的代码。 :)

以上是关于使用 Objective-C 到 UITableView 的 JSON 数据的主要内容,如果未能解决你的问题,请参考以下文章

需要关于使用 GCD 将块添加到队列(objective-c)的建议

markdown 使用从Objective-C到Cocoascript的回调

您如何使用 Objective-C 让声音文件自动播放到 iOS 应用程序并循环播放?

使用 Objective-C 将 CoreData 添加到现有项目中

使用 Objective-C 到 UITableView 的 JSON 数据

如何使用evaluateJavaScript 将数据从WKWebview 发送到HTML 文件| iOS | Objective-C