Q:

How do I get my Facebook GraphAPI Data Not to Repeat in UITableView?

I know this is probably a simple answer for anybody who is skilled at Objective-C, but I'm new to using Objective-C and I've been stuck on this problem for the past few days.  I've read a lot of stackoverflow threads on repeating cells and tried copying and pasting a lot of the answers but none seem to work for me.
I'm trying to put the data that I'm getting from Facebook SDK for iOS into a UITableView.  I've managed to get the data from the Facebook GraphAPI and into the UITableView, but the problem I can't get past is that the data from the last record that the app fetches from Facebook keeps repeating in all the cells.  In addition to that, when I scroll up or down, it takes a few seconds to populate the cell even though it already knows the data.
I've tried so many ways to get this to work, but solving this problem is beyond skill level. At this point I'll try anything to get this working properly and displaying the results I get from Facebook without causing the current problem, so any help will be very appreciated.
My NSLogs show two records but my UITableView will only show one.  Here's an example of my logs.
The follow data is from the UITableViewCell method in FBLeaderBoardTableViewController.m
Full Name: John Smith 
High Score: 5666 
Facebook ID: 654321 
Image: <UIImage: 0xde12345>
IndexPath Row: 1

*************************************

2013-12-26 11:51:48.380 [7820:70b] CREATING NEW CELL
2013-12-26 11:51:48.380 [7820:70b] indexPath.row: 1
2013-12-26 11:51:48.468 [7820:70b] 

The follow data is from the UITableViewCell method in FBLeaderBoardTableViewController.m
Full Name: Figurative Art 
High Score: 2762 
Facebook ID: 123456 
Image: <UIImage: 0x1101234>
IndexPath Row: 1

*************************************

2013-12-26 11:51:48.468 [7820:70b] CREATING NEW CELL
2013-12-26 11:51:48.469 [7820:70b] indexPath.row: 1
2013-12-26 11:51:48.553 [7820:70b] 

The follow data is from the UITableViewCell method in FBLeaderBoardTableViewController.m
Full Name: John Smith 
High Score: 5666 
Facebook ID: 654321 
Image: <UIImage: 0xde12345>
IndexPath Row: 0

*************************************

2013-12-26 11:51:48.553 [7820:70b] CREATING NEW CELL
2013-12-26 11:51:48.553 [7820:70b] indexPath.row: 0
2013-12-26 11:51:48.637 [7820:70b] 

The follow data is from the UITableViewCell method in FBLeaderBoardTableViewController.m
Full Name: Figurative Art 
High Score: 2762 
Facebook ID: 123456 
Image: <UIImage: 0x1101234>
IndexPath Row: 0

*************************************

2013-12-26 11:51:48.637 [7820:70b] CREATING NEW CELL
2013-12-26 11:51:48.637 [7820:70b] indexPath.row: 0
2013-12-26 11:51:48.720 [7820:70b] 

The follow data is from the UITableViewCell method in FBLeaderBoardTableViewController.m
Full Name: John Smith 
High Score: 5666 
Facebook ID: 654321 
Image: <UIImage: 0xde12345>
IndexPath Row: 2

*************************************

2013-12-26 11:51:48.720 [7820:70b] CREATING NEW CELL
2013-12-26 11:51:48.720 [7820:70b] indexPath.row: 2
2013-12-26 11:51:49.290 [7820:70b] 

The follow data is from the UITableViewCell method in FBLeaderBoardTableViewController.m
Full Name: Figurative Art 
High Score: 2762 
Facebook ID: 123456 
Image: <UIImage: 0x1101234>
IndexPath Row: 2

*************************************

Here is the code from my LeadeboardViewController.m
#import "FBLeaderBoardTableViewController.h"
#import "FBLeaderBoardCell.h"
#import "ViewController.h"

@interface FBLeaderBoardTableViewController ()

@end

@implementation FBLeaderBoardTableViewController

@synthesize facebookID, facebookFullName, facebookFirstName, facebookHighScore, facebookProfilePicture, tableView, closeFacebookLeaderboard;
@synthesize FBArray;
@synthesize FBMutableArray;

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self.tableView registerNib:[UINib nibWithNibName:@"FBLeaderBoardCell" bundle:nil ] forCellReuseIdentifier:@"FBLeaderBoardCellID"];

}

- (void)viewWillAppear:(BOOL)animated {

    [super viewWillAppear:animated];

}

- (IBAction)closeFacebookLeaderboard:(id)sender {

    [self dismissViewControllerAnimated:TRUE completion:nil];

}

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

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{

//    [self.tableView reloadData];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
    // Return the number of rows in the section.
    return 10;

    //RESULTS THAT DIDN'T WORK
    //return [displayData count];
    //return [self.data count];
    //return [FBLeaderBoardData count];
    //return [facebookHighScore count];
    //return [data count];

}

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

{

    static NSString *CellIdentifier = @"fbcell";
    FBLeaderBoardCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil)
    {

        cell = [[[FBLeaderBoardCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]autorelease];
        {
            NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"FBLeaderBoardCell" owner:nil options:nil];
            for (id currentObject in topLevelObjects){
                if([currentObject isKindOfClass:[FBLeaderBoardCell class]]){
                    cell = (FBLeaderBoardCell *)currentObject;

                }
            }

        }            [FBRequestConnection startWithGraphPath:[NSString stringWithFormat:@"xxxx/scores?fields=score,user"] parameters:nil HTTPMethod:@"GET" completionHandler:^(FBRequestConnection *connection, id result, NSError *error) {

            if (result && !error)
            {
                // int index = 0;
                for (NSDictionary *dict in [result objectForKey:@"data"])
                {
                    NSString *name = [[dict objectForKey:@"user"] objectForKey:@"name"];
                    NSString *highScore = [dict objectForKey:@"score"];
                    NSString *FBID = [[dict objectForKey:@"user"] objectForKey:@"id"];
                    NSString *imageURL = [[NSString alloc] initWithFormat:@"https://graph.facebook.com/%@/picture",FBID];
                    UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]]];
                    [imageURL release];
                    self.facebookFullName = name;
                    self.facebookHighScore = highScore;
                    self.facebookProfilePicture = image;

                    NSLog(@"\n\nThe follow data is from the UITableViewCell method in FBLeaderBoardTableViewController.m\nFull Name: %@ \nHigh Score: %@ \nFacebook ID: %@ \nImage: %@\nIndexPath Row: %ld\n\n*************************************\n\n", facebookFullName, facebookHighScore, FBID, facebookProfilePicture, (long)indexPath.row);
                    //                        NSLog(@"FBGraph Index Row: %d", indexPath.row);
                    NSLog(@"CREATING NEW CELL");
                    NSLog(@"indexPath.row: %d", indexPath.row);

                    cell.FBPlayerPhoto.image = facebookProfilePicture;
                    cell.FBPlayerName.text = facebookFullName;
                    cell.FBPlayerScore.text = [NSString stringWithFormat:@"$%@ Gold Coins",facebookHighScore];

                }
            }

        }];

//                [tableView reloadData];

    }

    return cell;
}

// Removes iOS 7 Staus bar from this view.
- (BOOL)prefersStatusBarHidden{
    return YES;
}

@end

Here's the code from my LeadeboardViewController.h
#import <UIKit/UIKit.h>
#import "FBLeaderBoardCell.h"
#import <FacebookSDK/FacebookSDK.h>

@interface FBLeaderBoardTableViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
{
    NSMutableArray *FBLeaderBoardData;
    IBOutlet UILabel *showScore;
    __block NSMutableArray* _itemsNamesFriend;
    __block NSArray* data;
    __block NSMutableArray* displayData;
//    IBOutlet FBProfilePictureView *facebookProfilePicture;
    IBOutlet UITableView *tableView;
    IBOutlet UIButton *closeFacebookLeaderboard;

}

@property (strong, nonatomic) NSArray *data;
@property (strong) NSString *facebookID;
@property (strong) NSString *facebookFullName;
@property (strong) NSString *facebookFirstName;
@property (strong) NSString *facebookHighScore;
@property (strong) UIImage *facebookProfilePicture;
//@property (strong) IBOutlet FBProfilePictureView *facebookProfilePicture;
@property (strong) IBOutlet UITableView *tableView;
@property (strong) IBOutlet UIButton *closeFacebookLeaderboard;
@property (strong, nonatomic) NSArray *FBArray;
@property (strong, nonatomic) NSMutableArray *FBMutableArray;

@end

I know the way I currently have the FBRequest in my - (UITableViewCell *) may not be the best way to call the data but when I tried to put it into the viewDidLoad method, I was getting NULL in my - (UITableViewCell *).  Figuring out how to do it as an NSArray or NSMutableArray kept causing me problems so I just put everything into the - (UITableViewCell *).

A:

The reason your code is repeating like that is because of this for loop in your cellForRowAtIndexPath method:
for (NSDictionary *dict in [result objectForKey:@"data"]) {

    NSString *name = [[dict objectForKey:@"user"] objectForKey:@"name"];
    NSString *highScore = [dict objectForKey:@"score"];
    NSString *FBID = [[dict objectForKey:@"user"] objectForKey:@"id"];
    NSString *imageURL = [[NSString alloc] initWithFormat:@"https://graph.facebook.com/%@/picture",FBID];
    UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]]];
    [imageURL release];
    self.facebookFullName = name;
    self.facebookHighScore = highScore;
    self.facebookProfilePicture = image;
    cell.FBPlayerPhoto.image = facebookProfilePicture;
    cell.FBPlayerName.text = facebookFullName;
    cell.FBPlayerScore.text = [NSString stringWithFormat:@"$%@ Gold Coins",facebookHighScore];

}

You're going through the dictionary while loading each individual row, so you're ending up setting your cell with the results generated during the final iteration.
So replace the loop with the single dictionary value correlated with the current particular row.  For example, you can just set dict = [[result objectForKey:@"data"] objectAtIndex:indexPath.row] and remove the for loop like so:
NSDictionary *dict = [[result objectForKey:@"data"] objectAtIndex:indexPath.row];

NSString *name = [[dict objectForKey:@"user"] objectForKey:@"name"];
NSString *highScore = [dict objectForKey:@"score"];
NSString *FBID = [[dict objectForKey:@"user"] objectForKey:@"id"];
NSString *imageURL = [[NSString alloc] initWithFormat:@"https://graph.facebook.com/%@/picture",FBID];
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:imageURL]]];
[imageURL release];
self.facebookFullName = name;
self.facebookHighScore = highScore;
self.facebookProfilePicture = image;
cell.FBPlayerPhoto.image = facebookProfilePicture;
cell.FBPlayerName.text = facebookFullName;
cell.FBPlayerScore.text = [NSString stringWithFormat:@"$%@ Gold Coins",facebookHighScore];

Edit: And a few more things, while we're at it…
(1)  You're making a similar error here:
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"FBLeaderBoardCell" owner:nil options:nil];
for (id currentObject in topLevelObjects){
    if([currentObject isKindOfClass:[FBLeaderBoardCell class]]){
        cell = (FBLeaderBoardCell *)currentObject;

    }
}

by repopulating the cell object during each iteration of the loop.  That's unnecessary.  Follow the method mentioned here to achieve loading a custom cell with a xib properly: https://stackoverflow.com/a/1939305/2274694
(2)  You may actually want to fetch the graph path results in a different method in your code for 2 reasons:  #1 It doesn't make sense to have your app call the Facebook graph path while loading every single row. And more importantly in your case, #2 in order to dynamically find out the number of rows during numberOfRowsInSection: you'll need to pre-fetch the results anyway.
So I suggest fetching the graph path results before each time the table loads, inserting a [tableView reloadData] statement within the block, keeping the results as a class variable, and setting the number of rows to results.count.

