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 trialDee Greene
8,508 PointsDisplay unread messages
I would like to update the inbox badge to display the number of unread messages (my messages don't self destruct, app is similar to iOS messages). When the user clicks on a messages and goes back to the inbox tab the badge should be updated. Also, I would like to mark the background color of the unread cells differently than the cells of read...that way the user knows what has been read and what hasn't. I have some working code but right now I am getting:
"Warning: A long-running operation is being executed on the main thread.
Break on warnBlockingOperationOnMainThread() to debug."
PFQuery *query = [PFQuery queryWithClassName:@"Messages"];
[query whereKey:@"recipientIds" equalTo:[[PFUser currentUser] objectId]];
[query orderByDescending:@"createdAt"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error) {
NSLog(@"Error: %@ %@", error, [error userInfo]);
} else {
// messages were found!
self.messages = objects;
//find unread messages
[query whereKey:@"readBy" notEqualTo:[[PFUser currentUser] objectId]];
self.unreadMessages = [query findObjects];
// set badge # to number of msgs
if (self.unreadMessages.count > 0) {
[[self navigationController] tabBarItem].badgeValue = [NSString stringWithFormat:@"%lu", (unsigned long)self.unreadMessages.count];
}
[self.tableView reloadData];
4 Answers
Dee Greene
8,508 PointsI have the code now working for displaying the correct badge number
PFQuery *query = [PFQuery queryWithClassName:@"Messages"];
[query whereKey:@"recipientIds" equalTo:[[PFUser currentUser] objectId]];
[query orderByDescending:@"createdAt"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error) {
NSLog(@"Error: %@ %@", error, [error userInfo]);
} else {
// messages were found!
self.messages = objects;
//find unread messages
[query whereKey:@"readBy" notEqualTo:[[PFUser currentUser] objectId]];
//start stackoverflow code
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error)
{
if (!error)
{
self.unreadMessages = [NSMutableArray arrayWithArray:objects];
//NSLog(@"unread: %@", self.unreadMessages);
// set badge # to number of msgs
if (self.unreadMessages.count > 0)
{
[[self navigationController] tabBarItem].badgeValue = [NSString stringWithFormat:@"%lu", (unsigned long)self.unreadMessages.count];
}
[self.tableView reloadData];
however, my code for updating the cell is not
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
PFObject *message = [self.messages objectAtIndex:indexPath.row];
cell.textLabel.text = [message objectForKey:@"senderEmail"];
if ([self.unreadMessages containsObject:message]) {
// color background gray, bold the font
}else{
// leave cell alone
}
Rashii Henry
16,433 PointsWassup bro,
I believe your problem is where you're finding the unread message. You're already running one query and since the query is executed there won't be an error so it moves on and tries to re-query the found objects in the first block.
THATS THE PROBLEM FOR THE ERROR MESSAGE. running two or more queries simultaneously before the first query can finish.
try calling it before reloadData and outside of the else condition. See what happens.
OR
since youre using notEqualTo, try using whereKey: containsString: if 'readBy' containsString:objectID then you know those are all read. Subtract those from the total count(of your readyBy array) to get your unread messages.
Rashii Henry
16,433 PointsSet a breakpoint on the PFObject *message line and step through and see if the object is nil. The key for the message object may be nil.
Dee Greene
8,508 PointsI made a "readBy" field and updated cellForRowAtIndexPath to
if ([[message objectForKey:@"readBy"] containsObject:[[PFUser currentUser] objectId]]) {
// read message found
cell.textLabel.font = [UIFont fontWithName:@"Helvetica-Bold" size:17.0f];
cell.textLabel.textColor = [UIColor blackColor];
}else{
// unread message found
cell.textLabel.textColor = [UIColor redColor];
cell.textLabel.font = [UIFont fontWithName:@"Helvetica-Bold" size:17.0f];
}
Rashii Henry
16,433 Pointsokay you used containsObject. It was pretty much the same thing i was suggesting you did with the PFQuery. Its good you found a solution.
Rashii Henry
16,433 PointsRashii Henry
16,433 Pointswhen are you calling your query? in the viewDidLoad?
Dee Greene
8,508 PointsDee Greene
8,508 PointsviewWillAppear