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
Elizabeth Hill
1,147 PointsRibbit friends
Ok so I have a couple problems with the ribbit app. http://teamtreehouse.com/library/build-a-selfdestructing-message-iphone-app-2/relating-users-in-parsecom/adding-checkmarks-when-the-table-view-is-loaded-2
1.The app won't show checkmarks in the edit friends page and the friends won't show up in the friends page.
I don't really understand how the app will crash if you loop through friends so is there a way to fix that?
Is there any way to create another UITableViewController that shows friends that are following you?
4 Answers
Brenden Konnagan
16,858 PointsHello Martha!
I will try my best to help... :-)
can you post a code snippet? that may help in answering your question.
can you provide some context to this question? I am not sure that I am understanding your issue.
there is of course a way to do that... :-) which part are you unsure of?
Patrick Serrano
13,834 PointsIt would be helpful if you posted the relevant code so we can try to spot where the problem you are having it. Be sure to format the code as code using markdown. (There is a handily link to the Markdown Cheatsheet below the textfield where you enter your post if you're unfamiliar with Markdown)
Elizabeth Hill
1,147 Pointshere is the code. I know this is a lot but its edit friends view controller and friends view controller. The checkmark won't show up in the edit friends view controller and the friends won't show up in the friends view controller. When I mean the app will crash is when Ben says in the beginning of the video that its easier to loop through friends but he prefers hashing and caching.
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;
for(PFUser *friend in self.friends) {
if ([friend.objectId isEqualToString:user.objectId]) {
[self.friends removeObject:friend];
break;
}
}
[friendsRelation removeObject:user];
}
else {
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
Elizabeth Hill
1,147 Pointsthis is frustrating
chitra iyer
3,722 PointsRegrading your first problem - no checkmarks in the edit friends page - did you implement the didSelectRowAtIndexPath method in EditFriends?
In the accessoryButtonTappedForRowWithIndexPath method that you have implemented, in the else block - where you validate if user is a friend, you have the following line of code
```cell.accessoryView = UITableViewCellAccessoryNone;
Elizabeth Hill
1,147 PointsElizabeth Hill
1,147 PointsI apologize if the code is not written right on the forum. I read the code cheat sheet and it is not working.
here is the code. I know this is a lot but its edit friends view controller and friends view controller. The checkmark won't show up in the edit friends view controller and the friends won't show up in the friends view controller. When I mean the app will crash is when Ben says in the beginning of the video that its easier to loop through friends but he prefers hashing and caching.
edit friends view controller.h
``` Objective C
import <UIKit/UIKit.h>
@interface EditfriendsViewController : UITableViewController @property (nonatomic, strong) NSArray *allUsers; @property (nonatomic, strong) PFUser *currentUser; @property (nonatomic, strong) NSMutableArray *friends;
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;
} else { 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)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"];
});
});
return cell; }
@end