使用 JSON 和 AFNetworking NSDictionary 使用数据填充 tableview

Posted

技术标签:

【中文标题】使用 JSON 和 AFNetworking NSDictionary 使用数据填充 tableview【英文标题】:populating a tableview with data using JSON and AFNetworking NSDictionary 【发布时间】:2014-06-05 21:16:36 【问题描述】:

这里是c & ios n00b,

我已经解决这个问题 3 天了。我担心我缺少一个基本概念。我已经研究并完成了与此相关的每个教程和堆栈溢出问题,但我无法得到答案。我正在尝试使用 json 文件中的数据填充我的 tableviewcontroller。我可以连接并从 JSON 文件输出,但我似乎无法解析字典并实际使用字典。这是我认为最接近正确的代码:

TABLEVIEW CONTROLLER
#import "AllTableViewController.h"
#import "AFHTTPRequestOperation.h"
#import "AFNetworking.h"
#import "UIImageView+AFNetworking.h"
#import "Beer.h"


@interface AllTableViewController ()

@end

@implementation AllTableViewController

- (id)initWithStyle:(UITableViewStyle)style

    self = [super initWithStyle:style];
    if (self) 
        // Custom initialization
    
    return self;


- (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;
    NSURL *URL = [NSURL URLWithString:@"http://www.hopshack.com/db_get_all_beer.php"];

    NSURLRequest *request = [NSURLRequest requestWithURL:URL];

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc]
                                         initWithRequest:request];
    operation.responseSerializer = [AFJSONResponseSerializer serializer];

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) 
        NSLog(@"%@",responseObject[@"beer"][3][@"name"]);
       NSMutableArray *tempArray=[[NSMutableArray alloc]init];
        for(NSDictionary *oneDictionary in responseObject)
            Beer *newBeer=[[Beer alloc]initWithName:oneDictionary[@"beer"][@"name"]];
            [tempArray addObject:newBeer];
        
        self.beers=[[NSArray alloc]initWithArray:tempArray];

     failure:^(AFHTTPRequestOperation *operation, NSError *error) 

        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error Retrieving Beer"
                                                            message:[error localizedDescription]
                                                           delegate:nil
                                                  cancelButtonTitle:@"Ok"
                                                  otherButtonTitles:nil];
        [alertView show];
    ];
    [operation start];




- (void)didReceiveMemoryWarning

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




- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView


    // Return the number of sections.
    return 1;


- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

    return self.beers.count;



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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"pCell" forIndexPath:indexPath];

    if(cell==nil)
        cell=[[UITableViewCell alloc]initWithStyle:(UITableViewCellStyleDefault) reuseIdentifier:@"pCell"];
    
    cell.textLabel.text=[self.beers[indexPath.row] name];
    return cell;

BEER MODEL
#import "Beer.h"
#import "AFHTTPRequestOperation.h"
#import "AFNetworking.h"
#import "UIImageView+AFNetworking.h"

@implementation Beer
-(id)initWithName:(NSString *)aName
    self=[super init];
    if(self)
        self.name=aName;
    
    return self;


@end

在此先感谢大家的帮助。本站规则。

【问题讨论】:

【参考方案1】:

如果您的 self.beers 数组已正确填充,那么我认为您没有重新加载 tableview。

self.beers=[[NSArray alloc]initWithArray:tempArray];之后添加这一行

dispatch_async(dispatch_get_main_queue(), ^
                [self.tableView reloadData]
            );

它会在你收到所有数据后重新加载 tableview。 如果这不起作用,那么 NSLog(@"%@",self.beers); 以确保 self.啤酒已满。

在实际填充 tableView 之前,我没有意识到它会给你一个错误。我认为问题在于name 返回的是NSString 而不是NSArray。实际上 responseObject 包含字典数组,因此当您遍历数组时,您会为每种啤酒获得一个字典。这样您就可以使用objectForKey访问啤酒名称

Beer *newBeer=[[Beer alloc]initWithName:[oneDictionary objectForKey@"name"]];

检索啤酒的名称。

如果成功了请告诉我。

【讨论】:

Yan,谢谢你的帮助,但这给我带来了与我得到的基本相同的运行时错误:` -[__NSCFString objectForKeyedSubscript:]: unrecognized selector sent to instance 0x8cb3b20 2014-06-08 12:34:53.580 HopShack[491:60b] *** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[__NSCFString objectForKeyedSubscript:]:无法识别的选择器发送到实例 0x8cb3b20` 有什么建议吗? Yan,另外,单步执行断点表示当我将对象添加到临时数组时,我的应用程序崩溃了 听起来你没有字典,你有一个字符串。尝试调试响应中返回的数据。 您也可以使用jsonformatter.curiousconcept.com 来格式化响应。这样,您将看到所有键的类型和值。

以上是关于使用 JSON 和 AFNetworking NSDictionary 使用数据填充 tableview的主要内容,如果未能解决你的问题,请参考以下文章

具有 setReachabilityStatusChangeBlock 支持的 AFNetworking EnqueueBatchOfHTTPRequestOperations

使用 AFNetworking 和模型类解析 JSON

iOS 解析 JSON 和 AFNetworking

使用 json 数据和使用 afnetworking 的多部分请求

AFNetworking 和 JSON 参数

AFNetworking、NSURLSession 和 json 响应 (Ronak Sankhala)