Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

iOS

Ribbit

So I am stuck on http://teamtreehouse.com/library/build-a-selfdestructing-message-iphone-app-2/relating-users-in-parsecom/adding-checkmarks-when-the-table-view-is-loaded-2

I really need help on this ribbit app. So the checkmarks are not showing up in the edit friends page and the friends are not showing up in the friends page. Also, in the beginning of this video Ben said the app will crash if we loop through friends (Not sure what that means) but is there a way to fix that?

edit friends view controller.h

#import <UIKit/UIKit.h>
#import <Parse/Parse.h>

@interface EditfriendsViewController : UITableViewController

@property (nonatomic, strong) NSArray *allUsers;
@property (nonatomic, strong) PFUser *currentUser;
@property (nonatomic, strong) NSMutableArray *friends;

- (BOOL)isFriend:(PFUser *)user;

@end

edit friends view controller.m

#import "EditfriendsViewController.h"

@interface EditfriendsViewController ()

@end

@implementation EditfriendsViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    PFQuery *query = [PFUser query];
    [query orderByAscending:@"username"];
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if (error) {
            NSLog(@"Error: %@ %@", error, [error userInfo]);
        }
        else {
            self.allUsers = objects;
            [self.tableView reloadData];

    }

    }];

    self.currentUser = [PFUser currentUser];
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{

    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

    // Return the number of rows in the section.
    return [self.allUsers count];
}

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

    PFUser *user = [self.allUsers objectAtIndex:indexPath.row];
    cell.textLabel.text = user.username;

     //APP CRASH through looping
    if ([self isFriend:user]) {
        //add checkmark
        cell.accessoryType = UITableViewCellAccessoryCheckmark;

    }
    else {
        //clear checkmark
        cell.accessoryType = UITableViewCellAccessoryNone;
    }

    return cell;
}

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
    [self.tableView deselectRowAtIndexPath:indexPath animated:NO];

   UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
    cell.accessoryType = UITableViewCellAccessoryCheckmark;
    PFRelation *friendsRelation = [self.currentUser relationForKey:@"friendsRelation"];
    PFUser *user = [self.allUsers objectAtIndex:indexPath.row];

    if ([self isFriend:user]) {
        //cell.accessoryView = nil;
        cell.accessoryView = nil;

        for(PFUser *friend in self.friends) {
            if ([friend.objectId isEqualToString:user.objectId]) {
                [self.friends removeObject:friend];
                break;
            }
        }
        [friendsRelation removeObject:user];
    }
         else {
             //replaced cell.accessoryview = uitableviewcellaccessorynone;
             cell.accessoryView = UITableViewCellAccessoryNone;
             [self.friends addObject:user];
             [friendsRelation addObject:user];
         }
         [self.currentUser saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
        if (error) {
            NSLog(@"Error: %@ %@", error, [error userInfo]);
        }
    }];
         }

   #pragma mark - Helper methods

//app will crash while looping
- (BOOL)isFriend:(PFUser *)user {
    for (PFUser *friend in self.friends) {
        if ([friend.objectId isEqualToString:user.objectId]) {
            return YES;
        }
    }

    return NO;

}

@end

friends view controller.h

#import <UIKit/UIKit.h>
#import <Parse/Parse.h>

@interface friendsViewController : UITableViewController

@property (nonatomic, strong) PFRelation *friendsRelation;
@property (nonatomic, strong) NSArray *friends;

@end

friends view controller.m

#import "friendsViewController.h"
#import "GravatarUrlBuilder.h"
#import "EditfriendsViewController.h"

@interface friendsViewController ()

@end

@implementation friendsViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    self.friendsRelation = [[PFUser currentUser] objectForKey:@"friendsRelation"];

    PFQuery *query = [self.friendsRelation query];
    [query orderByAscending:@"username"];
    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if (error) {
            NSLog(@"Error %@ %@", error, [error userInfo]);
        }
        else {
            self.friends = objects;
            [self.tableView reloadData];

        }

    }];

    }
//APP CRASH VIDEO
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"showEditFriends"]) {
        EditfriendsViewController *viewController = (EditfriendsViewController *)segue.destinationViewController;
        viewController.friends = [NSMutableArray arrayWithArray:self.friends];

         }
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{

    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

    // Return the number of rows in the section.
    return [self.friends count];
}

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

    PFUser *user = [self.friends objectAtIndex:indexPath.row];
    cell.textLabel.text = user.username;

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    dispatch_async(queue, ^{
        //get email address
        NSString *email = [user relationForKey:@"email"];

        //create md5 hash
        NSURL *gravatarUrl = [GravatarUrlBuilder getGravatarUrl:email];

        //request image from gravatar
        NSData *imageData = [NSData dataWithContentsOfURL:gravatarUrl];

        dispatch_async(dispatch_get_main_queue(), ^{ //set image in cell
            cell.imageView.image = [UIImage imageWithData:imageData];
            [cell setNeedsLayout];
     });

    });

     return cell;
}

@end

1 Answer

Just at first glance it seems you are setting in your cellForRowAtIndexPath method the accessoryType and then in your accessoryButtonTapped method you are setting accessoryView.

Id suggest looking through the docs, or download the project files Ben has put with the video's and compare your code to TH.

Hope this is of some help.