-2

I have created a view to display all users from user class on Parse server by using PFQueryTableViewController also with UISearchDisplayController in order to do filtering and searching. All of those features is working fine but there remains one problem that is when I tap a tableview cell to go to its user detail view I got this error:

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'

Here is my code:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
  PFUser *user = (tableView == self.tableView) ? self.objects[indexPath.row] : self.searchResults[indexPath.row];

  static NSString *identifier = @"reuseIdentifier";
  UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:identifier];
  if (!cell)
  {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                  reuseIdentifier:identifier];
  }

  // display user name
  NSString *userName = [NSString stringWithFormat:@"@%@", user.username];
  cell.textLabel.text = userName;
  cell.textLabel.textColor = [UIColor darkGrayColor];

  // tap user ????
  UITapGestureRecognizer * tap = [UITapGestureRecognizer new];
  [tap addTarget:self action:@selector(handleNameTap:)];
  cell.textLabel.userInteractionEnabled = YES;
  [cell.textLabel addGestureRecognizer:tap];
  //--????

  return cell;
}

- (void)handleNameTap:(UIGestureRecognizer *)tap 
{

  CGPoint touchLocation = [tap locationOfTouch:0 inView:self.tableView];
  NSIndexPath *tappedRow = [self.tableView indexPathForRowAtPoint:touchLocation];

  PAWOtherUserProfileViewController *otherProfileViewController = [[PAWOtherUserProfileViewController alloc] initWithNibName:nil bundle:nil];

  PAWUserProfileViewController *userProfileViewController = [[PAWUserProfileViewController alloc] initWithNibName:nil bundle:nil];

  PFQuery *query = [PFUser query];

  [query whereKey:kPAWParseUsernameKey equalTo:[self.searchResults objectAtIndex:tappedRow.row]];
  NSArray *userArray = [query findObjects];
  PFUser *user = [userArray objectAtIndex:0];

  if ([user.username isEqualToString:[PFUser currentUser].username]) {
    NSLog(@"current user");
    userProfileViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
    [self.navigationController presentViewController:userProfileViewController animated:YES completion:nil];
  } else {
    NSLog(@"other user");
    otherProfileViewController.userPassed = user;

    otherProfileViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
    [self.navigationController presentViewController:otherProfileViewController animated:YES completion:nil];
  }
}

Could anyone help point out what's wrong with my code or where I should look into? I have done some search about it and found most people use storyboard with segue technique but I'm not using storyboard. Thanks very much.

SanitLee
  • 1,253
  • 1
  • 12
  • 29
  • Can you post the full error message and stack trace? – NobodyNada Mar 22 '15 at 16:37
  • Can you symbolicate those return addresses please? – NobodyNada Mar 22 '15 at 16:43
  • To those who down voted this question, please help give me your reasons, so that I can avoid them next time. I'm new to programming but willing to learn. Thank you. – SanitLee Mar 26 '15 at 06:36
  • 1
    I downvoted because the return addresses weren't symbolicated. A bunch of return addresses in hex means absolutely nothing to us since you're the only one who has the `dSYM` to symbolicate them with. – NobodyNada Mar 26 '15 at 15:46
  • Thanks for your response. I have removed that added info from my question as my original question is enough to get answered. Hope you kind enough to reconsider your downvote as I am in risk being blocked from asking question. – SanitLee Mar 27 '15 at 03:06
  • 1
    2 out of ~15 downvoted questions isn't going to get you banned unless you have a whole bunch of deleted questions. – NobodyNada Mar 27 '15 at 03:09
  • Also, removing the un-symbolicated return addresses didn't make the question any better. Symbolicate them please!!! You're the only one with the `dSYM`! – NobodyNada Mar 27 '15 at 03:11
  • I don't know about symbolicate things yet and I've moved on to something else. Never mind, I am fine now ~ – SanitLee Mar 27 '15 at 03:24

1 Answers1

2

I assume the error is in this line:

PFUser *user = [userArray objectAtIndex:0];

UserArray is an empty array and you're trying to access the first element, which doesn't exist. You need to check whether you're userArray has at least one element. So your code should better look like this:

NSArray *userArray = [query findObjects];
if ([userArray count] == 0 { 
     //do nothing
     return;
}

PFUser *user = [userArray objectAtIndex:0];

EDIT:

You shouldn't use a TapRecognizer for each cell to recognize when it has been tapped. There is a UITableViewDelegate (https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UITableViewDelegate_Protocol/index.html) method for that: tableView:didSelectRowAtIndexPath:. Implement this method in your ViewController and throw away the gesture recognizer.

If you want to have the action happen only when the user taps exactly on that label, UILabel is still the wrong solution. Better use a UIButton.

A good read for getting started with TableViews: https://developer.apple.com/library/prerelease/ios/documentation/UserExperience/Conceptual/TableView_iPhone/AboutTableViewsiPhone/AboutTableViewsiPhone.html#//apple_ref/doc/uid/TP40007451-CH1-SW1

bhr
  • 2,279
  • 1
  • 23
  • 31
  • Even though your answer is not exactly what I did to solve my issue but it led to my solution. What I did is to replace: PFUser *user = [userArray objectAtIndex:0]; with PFUser *user = [userArray firstObject]; Thank you. – SanitLee Mar 23 '15 at 06:52