简体   繁体   中英

AFNetworking 2.0 parsed data not displaying in table view

my issue: no data is displaying in the table.

below is the code being used to retrieve the json object array and parse it using AFNetworking 2.0. I have a UIViewController where I placed a tableview with a prototype cell that has a reuse identifier EventCell. All I want is to display a title and an image in every cell. I get no errors at runtime.

NSDictionary+events.h

#import <Foundation/Foundation.h>

@interface NSDictionary (events)

- (NSString *)eventImage;
- (NSString *)eventTitle;
- (NSDate *)eventDate;
- (NSNumber *)eventPrice;
- (NSNumber *)eventTicketsTotal;
@end

NSDictionary+events.m

#import "NSDictionary+events.h"

@implementation NSDictionary (events)



- (NSString *)eventImage
{
    return self[@"event_image"];

}

- (NSString *)eventTitle
{
    return self[@"event_title"];

}

- (NSDate *)eventDate
{
    //    NSString *dateStr = self[@"date"]; // date = "2013-01-15";
    return [NSDate date];
}

- (NSNumber *)eventPrice
{
    NSString *cc = self[@"event_price"];
    NSNumber *n = @([cc intValue]);
    return n;
}

- (NSNumber *)eventTicketsTotal{
    NSString *cc = self[@"event_tickets_total"];
    NSNumber *n = @([cc intValue]);
    return n;
}

@end

NSDictionary+events_package.h

#import <Foundation/Foundation.h>

@interface NSDictionary (NSDictionary_events_package)

-(NSArray *)upcomingWeather;
@end

NSDictionary+events_package.m

#import "NSDictionary+events_package.h"

@implementation NSDictionary (NSDictionary_events_package)


- (NSArray *)upcomingWeather
{
    NSDictionary *dict = self[@"data"];
    return dict[@"events"];
}
@end

TDViewController.h

#import <UIKit/UIKit.h>
#import "NSDictionary+events.h"

@interface TDViewController : UIViewController <UITableViewDataSource, UITableViewDelegate>
@property(nonatomic, retain) UITableView *tableView;
@end

TDViewController.m

#import "TDViewController.h"

#import "UIImageView+AFNetworking.h"
#import "TDSecondViewController.h"
#import "NSDictionary+events_package.h"

static NSString * const BaseURLString = @"http://xx.zzz.yy.xx/test/";

@interface TDViewController ()

@property(strong) NSDictionary *events;

@end

@implementation TDViewController   

- (void)viewDidLoad
{
    [super viewDidLoad];

    // 1
    NSString *string = [NSString stringWithFormat:@"%@event_json.php?format=json", BaseURLString];
    NSLog(@"web service address: %@", string);

    NSURL *url = [NSURL URLWithString:string];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];

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

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {

        // 3
        self.events = (NSDictionary *)responseObject;
        NSLog(@"%@", responseObject);
        self.title = @"JSON Retrieved";

        [self.tableView reloadData];

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

        // 4
        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error Retrieving Events"
                                                            message:[error localizedDescription]
                                                           delegate:nil
                                                  cancelButtonTitle:@"Ok"
                                                  otherButtonTitles:nil];
        [alertView show];
    }];

    // 5
    [operation start];

}


- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if([segue.identifier isEqualToString:@"WeatherDetailSegue"]){
        UITableViewCell *cell = (UITableViewCell *)sender;
        NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];

        TDSecondViewController *wac = (TDSecondViewController *)segue.destinationViewController;

        NSDictionary *w;
        if (indexPath.section == 0) {
            {
                w = [self.events upcomingWeather][indexPath.row];
                //NSLog( @"this is w: %@", w );
            }
            wac.weatherDictionary = w;

        }
    }
}


#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    if(!self.events)
        return 0;

    NSArray *upcomingWeather = [self.events upcomingWeather];
    return [upcomingWeather count];
    NSLog( @"the count is %lu", (long)[upcomingWeather count]);
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"EventCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    NSDictionary *daysWeather = nil;


    NSArray *upcomingWeather = [self.events upcomingWeather];
    daysWeather = upcomingWeather[indexPath.row];
    NSLog( @"this is daysWeather: %@", daysWeather );
    cell.textLabel.text = [daysWeather eventTitle];
     NSLog(@"The content of arry is%@",daysWeather);

    NSURL *url = [NSURL URLWithString:daysWeather.eventImage];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    UIImage *placeholderImage = [UIImage imageNamed:@"placeholder"];

    __weak UITableViewCell *weakCell = cell;

    [cell.imageView setImageWithURLRequest:request
                          placeholderImage:placeholderImage
                                   success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {

                                       weakCell.imageView.image = image;
                                       [weakCell setNeedsLayout];

                                   } failure:nil];    
    return cell;
}

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Navigation logic may go here. Create and push another view controller.
}

@end

below is the nslog output I get when i run the project on the simulator (note not all of the nslog statements are displaying).

2014-04-06 21:47:04.592 iCLUB[9198:60b] webservice address:     
http://xx.zzz.yy.xx/test/event_json.php?format=json
2014-04-06 21:47:04.685 iCLUB[9198:60b] {
data =     {
    events =         (
                    {
            "event_date" = "7-5-2014";
            "event_id" = 22;
            "event_image" = "http://xx.zzz.yy.xx/...";
            "event_price" = 150;
            "event_tickets_total" = 200;
            "event_title" = "New Event Title";
        },
                    {
            "event_date" = "3-2-2014";
            "event_id" = 23;
            "event_image" = "http://xx.zzz.yy.xx/...";
            "event_price" = 150;
            "event_tickets_total" = 200;
            "event_title" = "New Event Title 2";
        },
                    {
            "event_date" = "9-25-2014";
            "event_id" = 24;
            "event_image" = "http://xx.zzz.yy.xx/...";
            "event_price" = 150;
            "event_tickets_total" = 200;
            "event_title" = "New Event Title 33";
        }
    );
};
}

I just can't catch what the issue is, the app builds and runs on the simulator, but the cells appear completely empty. I would greatly appreciate any help. Thanks, JT.

Possible sources of the problem include:

  • Failure to connect the IBOutlet for the table view. If the tableView property is not hooked up properly, it would be nil , and thus [self.tableView reloadData] would do nothing (because sending a message to a nil object does nothing).

    Frankly, I'm unclear how this tableView property is getting set, because it lacks the typical IBOutlet qualification used when connecting controls in Interface Builder and I don't see you setting it programmatically, either.

  • Failure to specify your view controller as the delegate and, more importantly, the dataSource of the table view. If this is the case, even if you successfully called [self.tableView reloadData] , it would not result in the UITableViewDataSource methods being called).

I'd suggest checking that self.tableView and self.tableView.dataSource are non- nil .

  1. This NSLog statement in numberOfRowsInSection won't ever be called because the method returns before the statement!

      return [upcomingWeather count]; NSLog( @"the count is %lu", (long)[upcomingWeather count]); 
  2. It seems like cellForRowAtIndexPath is not getting called, which can be due to various reasons including the UITableView datasource and delegate not being set, numberOfRowsInSection returning 0, or your TableView being nil. Using the debugger will allow you to see which of these scenarios is happening.

    Check out Apple's resources on debugging.

When you parse json data , use above code

NSDictionary *dict = (NSDictionary *)responseObject;
    self.events = [dict objectForKey:@"data"];

Did you remember to set the delegate and dataSource for self.tableView? It's not done for you automatically when you don't subclass UITableViewController.

I believe the JSON you're getting from the API is invalid. The Array of events should be enclosed in brackets [] not parentheses. Additionally, JSON doesn't use semicolons. See the JSON spec .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM