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 Build a Self-Destructing Message iPhone App Retrieving and Viewing Data from Parse.com Deleting Data from Parse.com

Lei zheng
Lei zheng
7,990 Points

I try to complie this Ribbit. I am using Xcode 6.1 it report error.

I try to complie this Ribbit. I am using Xcode 6.1 I have changed parse app key and client key, and add parse frame, bolt frame, and according the tips, I have added libsql3.0.lib.

it compile ok.

but then it will stop, in the console output,

2014-12-29 13:00:24.430 Ribbit[12063:2254528] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Cannot do a comparison query for type: (null)' *** First throw call stack: ( 0 CoreFoundation 0x00000001078cff35 exceptionPreprocess + 165 1 libobjc.A.dylib 0x00000001062ebbb7 objc_exception_throw + 45 2 CoreFoundation 0x00000001078cfe6d +[NSException raise:format:] + 205 3 Ribbit 0x000000010350a6d8 +[PFInternalUtils assertValidClassForQuery:] + 333 4 Ribbit 0x00000001034df4de -[PFQuery whereKey:equalTo:] + 86 5 Ribbit 0x00000001034a5b86 -[InboxViewController viewWillAppear:] + 230 6 UIKit 0x0000000104cbd821 -[UIViewController _setViewAppearState:isAnimating:] + 487 7 UIKit 0x0000000104ce8960 -[UINavigationController _startTransition:fromViewController:toViewController:] + 776 8 UIKit 0x0000000104ce9487 -[UINavigationController _startDeferredTransitionIfNeeded:] + 523 9 UIKit 0x0000000104ce9f47 -[UINavigationController __viewWillLayoutSubviews] + 43 10 UIKit 0x0000000104e2f509 -[UILayoutContainerView layoutSubviews] + 202 11 UIKit 0x0000000104c0d973 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 521 12 QuartzCore 0x000000010465ede8 -[CALayer layoutSublayers] + 150 13 QuartzCore 0x0000000104653a0e _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380 14 QuartzCore 0x000000010465387e _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24 15 QuartzCore 0x00000001045c163e _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242 16 QuartzCore 0x00000001045c274a _ZN2CA11Transaction6commitEv + 390 17 UIKit 0x0000000104b9254d -[UIApplication _reportMainSceneUpdateFinished:] + 44 18 UIKit 0x0000000104b93238 -[UIApplication _runWithMainScene:transitionContext:completion:] + 2642 19 UIKit 0x0000000104b91bf2 -[UIApplication workspaceDidEndTransaction:] + 179 20 FrontBoardServices 0x0000000109d352a3 __31-[FBSSerialQueue performAsync:]_block_invoke + 16 21 CoreFoundation 0x000000010780553c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK + 12 22 CoreFoundation 0x00000001077fb285 __CFRunLoopDoBlocks + 341 23 CoreFoundation 0x00000001077fb045 __CFRunLoopRun + 2389 24 CoreFoundation 0x00000001077fa486 CFRunLoopRunSpecific + 470 25 UIKit 0x0000000104b91669 -[UIApplication _run] + 413 26 UIKit 0x0000000104b94420 UIApplicationMain + 1282 27 Ribbit 0x00000001034a44c3 main + 115 28 libdyld.dylib 0x0000000106669145 start + 1 29 ??? 0x0000000000000001 0x0 + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException (lldb)

3 Answers

Stone Preston
Stone Preston
42,016 Points

alright you probably need to move the current user if else statement from viewDidLoad into viewWillAppear. that way you only query for messages if the user is logged in

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

 PFUser *currentUser = [PFUser currentUser];
    if (currentUser) {
        NSLog(@"Current user: %@", currentUser.username);
        //query for messages
           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 {
            // We found messages!
            self.messages = objects;
            [self.tableView reloadData];
            NSLog(@"Retrieved %d messages", [self.messages count]);
        }
    }];

    }
    else {
        [self performSegueWithIdentifier:@"showLogin" sender:self];
    }

}

Thx for your solution!!!

Stone Preston
Stone Preston
42,016 Points

reason: 'Cannot do a comparison query for type: (null)'

your query is using a null object. probably something like [query whereKey:someKey equalTo:someObject] and someObject is null.

does this happen in the inbox? if so post your inbox code

Lei zheng
Lei zheng
7,990 Points

// // InboxViewController.m // Ribbit // // Copyright (c) 2013 Treehouse. All rights reserved. //

import "InboxViewController.h"

import "ImageViewController.h"

@interface InboxViewController ()

@end

@implementation InboxViewController

  • (void)viewDidLoad { [super viewDidLoad];

    self.moviePlayer = [[MPMoviePlayerController alloc] init];

    PFUser *currentUser = [PFUser currentUser]; if (currentUser) { NSLog(@"Current user: %@", currentUser.username); } else { [self performSegueWithIdentifier:@"showLogin" sender:self]; } }

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

    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 { // We found messages! self.messages = objects; [self.tableView reloadData]; NSLog(@"Retrieved %d messages", [self.messages count]); } }]; }

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.messages count]; }

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

    PFObject *message = [self.messages objectAtIndex:indexPath.row]; cell.textLabel.text = [message objectForKey:@"senderName"];

    NSString *fileType = [message objectForKey:@"fileType"]; if ([fileType isEqualToString:@"image"]) { cell.imageView.image = [UIImage imageNamed:@"icon_image"]; } else { cell.imageView.image = [UIImage imageNamed:@"icon_video"]; }

    return cell; }

pragma mark - Table view delegate

  • (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { self.selectedMessage = [self.messages objectAtIndex:indexPath.row]; NSString *fileType = [self.selectedMessage objectForKey:@"fileType"]; if ([fileType isEqualToString:@"image"]) { [self performSegueWithIdentifier:@"showImage" sender:self]; } else { // File type is video PFFile *videoFile = [self.selectedMessage objectForKey:@"file"]; NSURL *fileUrl = [NSURL URLWithString:videoFile.url]; self.moviePlayer.contentURL = fileUrl; [self.moviePlayer prepareToPlay]; [self.moviePlayer thumbnailImageAtTime:0 timeOption:MPMovieTimeOptionNearestKeyFrame];

    // Add it to the view controller so we can see it
    [self.view addSubview:self.moviePlayer.view];
    [self.moviePlayer setFullscreen:YES animated:YES];
    

    }

    // Delete it! NSMutableArray *recipientIds = [NSMutableArray arrayWithArray:[self.selectedMessage objectForKey:@"recipientIds"]]; NSLog(@"Recipients: %@", recipientIds);

    if ([recipientIds count] == 1) { // Last recipient - delete! [self.selectedMessage deleteInBackground]; } else { // Remove the recipient and save [recipientIds removeObject:[[PFUser currentUser] objectId]]; [self.selectedMessage setObject:recipientIds forKey:@"recipientIds"]; [self.selectedMessage saveInBackground]; }

}

  • (IBAction)logout:(id)sender { [PFUser logOut]; [self performSegueWithIdentifier:@"showLogin" sender:self]; }

  • (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if ([segue.identifier isEqualToString:@"showLogin"]) { [segue.destinationViewController setHidesBottomBarWhenPushed:YES]; } else if ([segue.identifier isEqualToString:@"showImage"]) { [segue.destinationViewController setHidesBottomBarWhenPushed:YES]; ImageViewController *imageViewController = (ImageViewController *)segue.destinationViewController; imageViewController.message = self.selectedMessage; } }

@end

I had the same problem, nobody answered me in the forum but I found a solution. I don't know why the Ben's code works. When I run his code the app crashes. I wrote my solution here: https://teamtreehouse.com/forum/value-of-type-nsuinteger-should-not-be-used-as-format-arguments