简体   繁体   中英

JSON data not loading in UITableView

I have a function that pings ebay and returns JSON to the iOS app. What I want to do is populate my UITableView with the JSON being returned. I've set up the code to the best of my understanding of how this should work, however the table loads without any data. I think this may be because the table is loading before the JSON is returned, not sure how to fix that though.

MatchCenterViewController.h

#import <UIKit/UIKit.h>
#import <Parse/Parse.h>
#import "AsyncImageView.h"
#import "SearchViewController.h"

@interface MatchCenterViewController : UIViewController <UITableViewDataSource>

@property (nonatomic) IBOutlet NSString *itemSearch;
@property (nonatomic, strong) NSArray *imageURLs;

@property (strong, nonatomic) NSString *matchingCategoryCondition;
@property (strong, nonatomic) NSString *matchingCategoryLocation;
@property (strong, nonatomic) NSNumber *matchingCategoryMaxPrice;
@property (strong, nonatomic) NSNumber *matchingCategoryMinPrice;


@property (strong, nonatomic) NSArray *matchCenterArray;


@end

MatchCenterViewController.m:

#import "MatchCenterViewController.h"
#import <UIKit/UIKit.h>

@interface MatchCenterViewController () <UITableViewDataSource, UITableViewDelegate>
@property (weak, nonatomic) IBOutlet UITableView *matchCenter;
@end

@implementation MatchCenterViewController



- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{

    [super viewDidLoad];


    //perform search with criteria just submitted
    [PFCloud callFunctionInBackground:@"MatchCenterTest"
                       withParameters:@{
                                        @"test": @"Hi",
                                        }
                                block:^(NSDictionary *result, NSError *error) {




                                    if (!error) {
                                        self.matchCenterArray = [result objectForKey:@"Top 3"];

                                        NSLog(@"Test Result: '%@'", result);
                                    }
                                }];

    self.matchCenterArray = [[NSArray alloc] init];
}

- (void)viewDidAppear:(BOOL)animated
{


    [PFCloud callFunctionInBackground:@"MatchCenterTest"
                       withParameters:@{
                                        @"test": @"Hi",
                                        }
                                block:^(NSDictionary *result, NSError *error) {

                                    if (!error) {
                                        NSLog(@"Test Result: '%@'", result);
                                    }
                                }];



}

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

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.matchCenterArray count];
}



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


    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    NSDictionary *matchCenterDictionary= [self.matchCenterArray objectAtIndex:indexPath.row];

    cell.textLabel.text = [matchCenterDictionary objectForKey:@"Title"];

    if([matchCenterDictionary objectForKey:@"Price"] != NULL)
    {
        cell.detailTextLabel.text = [NSString stringWithFormat:@"$%@",[matchCenterDictionary   objectForKey:@"Price"]];
    }

    return cell;


}


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




/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

JSON being returned:

{
    "Top 3" =     (
                {
            "Item 1" =             (
                                {
                    Title = "Apple iPhone 5s (Latest Model) - 16GB - Silver (AT&T) Smartphone";
                },
                                {
                    Price = "400.0";
                },
                                {
                    "Image URL" = "http://thumbs2.ebaystatic.com/m/mewfVG0QbBiu1nZytMuAlZw/140.jpg";
                },
                                {
                    "Item URL" = "http://www.ebay.com/itm/Apple-iPhone-5s-Latest-Model-16GB-Silver-AT-T-Smartphone-/181431570117?pt=Cell_Phones";
                }
            );
        },
                {
            "Item 2" =             (
                                {
                    Title = "Apple iPhone 5c (Latest Model) - 16GB - Pink (Verizon) Smartphone";
                },
                                {
                    Price = "350.0";
                },
                                {
                    "Image URL" = "http://thumbs4.ebaystatic.com/m/mMPAT67KjfCZF9oorbTf3uw/140.jpg";
                },
                                {
                    "Item URL" = "http://www.ebay.com/itm/Apple-iPhone-5c-Latest-Model-16GB-Pink-Verizon-Smartphone-/191204844039?pt=Cell_Phones";
                }
            );
        },
                {
            "Item 3" =             (
                                {
                    Title = "Apple iPhone 5 \U2013 16GB, White, works with Virgin Mobile US \U2013 NEW";
                },
                                {
                    Price = "359.99";
                },
                                {
                    "Image URL" = "http://thumbs3.ebaystatic.com/m/m5x1uj1iSS2fr691tifrvrw/140.jpg";
                },
                                {
                    "Item URL" = "http://www.ebay.com/itm/Apple-iPhone-5-16GB-White-works-Virgin-Mobile-US-NEW-/141227441998?pt=Cell_Phones";
                }
            );
        }
    );
}

在此处输入图片说明在此处输入图片说明

Reload your table on the main thread after your data is loaded.

In your completion block:

[PFCloud callFunctionInBackground:@"MatchCenterTest"
                   withParameters:@{
                                    @"test": @"Hi",
                                    }
                            block:^(NSDictionary *result, NSError *error) {

                                if (!error) {
                                    dispatch_async(dispatch_get_main_queue(), ^{
                                        self.matchCenterArray = [result objectForKey:@"Top 3"];
                                        [matchCenter reloadData];
                                    });
                                    NSLog(@"Test Result: '%@'", result);
                                }
                            }];

Edit1: Also, I would recommend adapting to your protocols in one place. Right now you're using UITableViewDataSource in your header file, and then both UITableViewDataSource and UITableViewDelegate in your implementation file. Stick to one location for best practices.


Edit2: Relocated line to set the matchCenterArray contents onto the main thread dispatch per @Rob's suggestion in the comments


Edit3: Based on comments, you have the ability to change your JSON. Your current structure listed above is quite cumbersome, so I would suggest something more concise (and more easily parse-able) like this:

    {
    "Top 3" : [
        {
            "Title" : "Apple iPhone 5s (Latest Model) - 16GB - Silver (AT&T) Smartphone",
            "Price" : "400.0",
            "Image URL" : "http://thumbs2.ebaystatic.com/m/mewfVG0QbBiu1nZytMuAlZw/140.jpg",
            "Item URL" : "http://www.ebay.com/itm/Apple-iPhone-5s-Latest-Model-16GB-Silver-AT-T-Smartphone-/181431570117?pt:Cell_Phones"
        },
        {
            "Title" : "Apple iPhone 5c (Latest Model) - 16GB - Pink (Verizon) Smartphone",
            "Price" : "350.0",
            "Image URL" : "http://thumbs4.ebaystatic.com/m/mMPAT67KjfCZF9oorbTf3uw/140.jpg",
            "Item URL" : "http://www.ebay.com/itm/Apple-iPhone-5c-Latest-Model-16GB-Pink-Verizon-Smartphone-/191204844039?pt:Cell_Phones"
        },
        {
            "Title" : "Apple iPhone 5 16GB, White, works with Virgin Mobile US NEW",
            "Price" : "359.99",
            "Image URL" : "http://thumbs3.ebaystatic.com/m/m5x1uj1iSS2fr691tifrvrw/140.jpg",
            "Item URL" : "http://www.ebay.com/itm/Apple-iPhone-5-16GB-White-works-Virgin-Mobile-US-NEW-/141227441998?pt:Cell_Phones"
        }
    ]
}

Now you can access your values like so:

// In your completion block:
self.matchCenterArray = [result objectForKey:@"Top 3"];

...
[[self.matchCenterArray objectAtIndex:0] objectForKey:@"Title"] // title of the first object
[[self.matchCenterArray objectAtIndex:2] objectForKey:@"Image URL"] // image URL of the last item

Just reload your table view in the block when you receive data from the cloud.

- (void)viewDidLoad
{

[super viewDidLoad];

self.matchCenterArray = [[NSArray alloc] init];
//perform search with criteria just submitted
[PFCloud callFunctionInBackground:@"MatchCenterTest"
                   withParameters:@{
                                    @"test": @"Hi",
                                    }
                            block:^(NSDictionary *result, NSError *error) {




                                if (!error) {
                                    self.matchCenterArray = [result objectForKey:@"Top 3"];
[yourTableView reloadData];
                                    NSLog(@"Test Result: '%@'", result);
                                }
                            }];


}

Also include UITableViewDelagete in your .h file. And init your array before the block.

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