0
votes

I created UITableView inside UIView (UserListVC) to display user data stored in a column typed array on Parse.com. The column called "followers" contains the array of PFUser objectId who did like the user in a row (in this case is current user).

In userListVC.m:

@implementation UserListViewController
{
    NSMutableArray *tableData;
}    

- (void)viewDidLoad {
[super viewDidLoad];

/*
tableData = [NSMutableArray arrayWithObjects:@"user1", @"user2", nil];
NSLog(@"tableData --> %@", tableData);
*/
tableData = [[NSMutableArray alloc] init];  

PFQuery *userQuery = [PFQuery queryWithClassName:kPAWParseUserClassKey];
[userQuery whereKey:kPAWParseUsernameKey equalTo:[PFUser currentUser].username];
userQuery.cachePolicy = kPFCachePolicyNetworkElseCache;
[userQuery findObjectsInBackgroundWithBlock:^(NSArray *users, NSError *error)
 {
     if( !error )
     {
         NSArray *array = [users valueForKey:@"followings"];
         for (int i = 0; i <= array.count; i++)

             PFQuery *followingsQuery = [PFUser query];
             [followingsQuery whereKey:@"objectId" equalTo:[[[users valueForKey:@"followings"] objectAtIndex:0] objectAtIndex:i]];
             followingsQuery.cachePolicy = kPFCachePolicyNetworkElseCache;

             [followingsQuery findObjectsInBackgroundWithBlock:^(NSArray *followings, NSError *error) {
                 if (!error) {
                     NSLog(@"following names --> %@", [followings valueForKey:kPAWParseUsernameKey]);

                     [tableData addObject:[followings valueForKey:kPAWParseUsernameKey]]; //??
                     [self.tableView reloadData];
                     NSLog(@"table data --> %@", tableData);
                 }
             }];
     }
 }];
}

I am now able to extract usernames from the user class by using data array that I get from "followers" column and I also have [self.tableView reloadData]; in async query block but there is still a problem with tableview not showing usernames obtained from tableData. If I use sample data ("user1","user2") just for testing, there is no problem.

Here below I show my log from the code:

2014-12-31 11:05:00.626 Test[12354:60b] following names --> (
user1name
)
2014-12-31 11:05:00.628 Test[12354:60b] table data --> (
    (
    user1name
    )
)
2014-12-31 11:05:00.631 Test[12354:60b] following names --> (
user2name
)
2014-12-31 11:05:00.633 Test[12354:60b] table data --> (
    (
    user1name
    ),
    (
    user2name
    )
)

I think it is better to also provide code for the method (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath and here it is:

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

static NSString *tableIdentifier = @"TableItem";

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:tableIdentifier];

if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:tableIdentifier];
}
NSLog(@"table data xxxxx --> %@", tableData);
cell.textLabel.text = [tableData objectAtIndex:indexPath.row];

return cell;
}

The above method NEVER runs but if I test with my sample data, it does run. To be more specific, my questions would be:

  • This is UIView with UITableView inside it. I am not sure how to do [self.tableView reloadData]; properly. I mean how to declare tableView. In this case I do this:

    @interface UserListViewController ()
    @property (weak, nonatomic) UITableView *tableView;//????
    @end
    
  • Why the method (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath never get run?

1
What code are you using to "obtain the username from the user class by using data array that I get from "followers" column"? - Lyndsey Scott
I don't know how to do that yet. I have been through a lot of searches but yet to find one. - SanitLee
@SanitLee Yep, you're 100% right! You can update your tableView inside your async block using [self.tableView reloadData]; after your [tableData addObject:[followings valueForKey:kPAWParseUsernameKey]]; //?? line. Great job figuring mostly everything out on your own! - Lyndsey Scott
@SanitLee Yeah, that tableData log will still be empty because the tableData isn't ready by the time that line's called since the tableData's being populated in the background during an async block. But if you just need to reload the tableview, do so within the async block. If you want to print out the table data, you'll also have to do so after the line I mentioned in the async block. - Lyndsey Scott
@SanitLee No, you can just reload the table inside the async block like I said. - Lyndsey Scott

1 Answers

0
votes

Just to answer these 2 specific questions:

  • Connect tableView to IBOutlet in .h file and synthesise it in .m file, then:

    [self.tableView reloadData];
    

do the above inside async block.

  • The method (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath will get run if do as the above suggests.

However there remains other issues but they are out of the scope of this question I believe.