Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

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.