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 Implementing Designs for iPhone Implementing Custom Login and Sign Up Screens Getting up to Speed

Nick Barnes
Nick Barnes
7,818 Points

Ribbit Crash - Cannot do a comparison query for type: (null)

I am using Xcode 6 GM Seed and whenever I try to run the Ribbit app, I get the following error:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Cannot do a comparison query for type: (null)'

The app crashes after it leaves didFinishLaunchingWithOptions, I don't see any of the view controllers. I have updated to the latest Parse version due to Mach-O linker errors but other than that, I haven't changed anything in the project - I downloaded it from the 'Getting up to speed' page.

Any ideas how to fix this so I can complete the last course in the iOS track?

Thanks. Nick

2014-09-14 21:34:10.526 Ribbit[16755:2489351] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Cannot do a comparison query for type: (null)'
*** First throw call stack:
(
    0   CoreFoundation                      0x0000000111f653f5 __exceptionPreprocess + 165
    1   libobjc.A.dylib                     0x0000000110f39bb7 objc_exception_throw + 45
    2   CoreFoundation                      0x0000000111f6532d +[NSException raise:format:] + 205
    3   Ribbit                              0x000000010e168859 +[PFInternalUtils assertValidClassForQuery:] + 306
    4   Ribbit                              0x000000010e152272 -[PFQuery whereKey:equalTo:] + 87
    5   Ribbit                              0x000000010e134b70 -[InboxViewController viewWillAppear:] + 336
    6   UIKit                               0x000000010f91feef -[UIViewController _setViewAppearState:isAnimating:] + 487
    7   UIKit                               0x000000010f94aed0 -[UINavigationController _startTransition:fromViewController:toViewController:] + 776
    8   UIKit                               0x000000010f94b9f7 -[UINavigationController _startDeferredTransitionIfNeeded:] + 523
    9   UIKit                               0x000000010f94c4b7 -[UINavigationController __viewWillLayoutSubviews] + 43
    10  UIKit                               0x000000010fa90399 -[UILayoutContainerView layoutSubviews] + 202
    11  UIKit                               0x000000010f870199 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 521
    12  QuartzCore                          0x000000010f2c1f98 -[CALayer layoutSublayers] + 150
    13  QuartzCore                          0x000000010f2b6bbe _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
    14  QuartzCore                          0x000000010f2b6a2e _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
    15  QuartzCore                          0x000000010f224ade _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242
    16  QuartzCore                          0x000000010f225bea _ZN2CA11Transaction6commitEv + 390
    17  UIKit                               0x000000010f7f567d -[UIApplication _reportMainSceneUpdateFinished:] + 44
    18  UIKit                               0x000000010f7f6368 -[UIApplication _runWithMainScene:transitionContext:completion:] + 2642
    19  UIKit                               0x000000010f7f4d22 -[UIApplication workspaceDidEndTransaction:] + 179
    20  FrontBoardServices                  0x0000000114a7e2a3 __31-[FBSSerialQueue performAsync:]_block_invoke + 16
    21  CoreFoundation                      0x0000000111e9aabc __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
    22  CoreFoundation                      0x0000000111e90805 __CFRunLoopDoBlocks + 341
    23  CoreFoundation                      0x0000000111e905c5 __CFRunLoopRun + 2389
    24  CoreFoundation                      0x0000000111e8fa06 CFRunLoopRunSpecific + 470
    25  UIKit                               0x000000010f7f4799 -[UIApplication _run] + 413
    26  UIKit                               0x000000010f7f7550 UIApplicationMain + 1282
    27  Ribbit                              0x000000010e133313 main + 115
    28  libdyld.dylib                       0x00000001132a3145 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

13 Answers

Stone Preston
Stone Preston
42,016 Points

yes I would move the following code to the beginning of viewWillAppear, and if the user is logged in, run the query, if not, show the login screen. not sure why your segue is not taking you to login, add some NSLogs to check:

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

PFUser *currentUser = [PFUser currentUser];
    if (currentUser) {
        NSLog(@"Current user: %@", currentUser.username);
        PFQuery *query = [PFQuery queryWithClassName:@"Messages"];
        [query whereKey:@"recipientIds" equalTo:[[PFUser currentUser] objectId]];
        //run the query here
    }
    else {
        [self performSegueWithIdentifier:@"showLogin" sender:self];
        NSLog(@"user not logged in");
    }

}
Andrew Brotherton
Andrew Brotherton
7,515 Points
#import "InboxTableViewController.h"
#import "ImageViewController.h"


@interface InboxTableViewController ()

@end

@implementation InboxTableViewController




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

#pragma mark- Table View data source    

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)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 didDeselectRowAtIndexPath:(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 it
        [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
Ben Jakuben
Ben Jakuben
Treehouse Teacher

Can you try Stone's suggestion from above? Move the following lines from viewDidLoad to viewWillAppear. Then move the code currently in your viewWillAppear method to where we have the comment // run query here:

PFUser *currentUser = [PFUser currentUser];
if (currentUser) {
    NSLog(@"Current user: %@", currentUser.username);
    // run query here
}
else {
    [self performSegueWithIdentifier:@"showLogin" sender:self];
}
Alex Romanillos
Alex Romanillos
16,144 Points

I had the same issue, changing the logged user if statement to viewWillAppear fixed the problem for me. Thanks Ben.

Hayden Pennington
Hayden Pennington
6,154 Points

Ben's solution worked for me running Xcode 6.3 and IOS 8.3. Thanks!

Andrew Brotherton
Andrew Brotherton
7,515 Points

Ben Jakuben

 014-09-25 11:19:58.379 Ribbit[18752:1409517] nested push animation can result in corrupted navigation bar
2014-09-25 11:19:58.767 Ribbit[18752:1409517] Finishing up a navigation transition in an unexpected state. Navigation Bar subview tree might get corrupted.
2014-09-25 11:20:15.928 Ribbit[18752:1409517] -[UINavigationItem text]: unrecognized selector sent to instance 0x7f9688f3b0c0
2014-09-25 11:20:15.934 Ribbit[18752:1409517] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UINavigationItem text]: unrecognized selector sent to instance 0x7f9688f3b0c0'
Trevor Duersch
Trevor Duersch
9,964 Points

I just barely started getting these errors. I just followed Stone Preston's advice and I got my app working again! :)

Thanks!

Here is what my viewWillAppear (InboxViewController) looks like -

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

    PFUser *currentUser = [PFUser currentUser];
    if (currentUser) {
        NSLog(@"Current user: %@", currentUser.username);
        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 %lu messages", (unsigned long)[self.messages count]);
            }
        }];
    } else {
        [self performSegueWithIdentifier:@"showLogin" sender:self];
        NSLog(@"User not logged in.");
    }
}
JIHOON JUNG
JIHOON JUNG
10,927 Points

had same issue but solved by your code #Trevor Duersch Thanks

Stone Preston
Stone Preston
42,016 Points

there is a query somewhere that is throwing the exception. do you have an exception breakpoint set? try setting an exception breakpoint by selecting debug -> breakpoints -> create exception brekpont then build and run and see if it will show you where the line of code is that is throwing the error

Nick Barnes
Nick Barnes
7,818 Points

Hi Stone, thanks for getting back to me. I created the execution breakpoint (which I didn't know about, thanks!) and it stems from the following line in InboxViewController.m

[query whereKey:@"recipientIds" equalTo:[[PFUser currentUser] objectId]];

The code up to that line is as follows:

#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]];

    ....

So am I right in thinking the query can't run because [PFUser currentUser] == nil ? I tried to move the following code to the beginning of the viewWillAppear method to set currentUser but nothing happens when it sends the [self performSegueWIthIdentifier:@"showLogin" sender:self] message, the screen just stays blank and it moves on to the offending line where it then breaks.

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

How can I make sure the app allows the user to login/signup when needed before moving on to query the list of messages received?

Thanks again for your help

Andrew Brotherton
Andrew Brotherton
7,515 Points

I'm receiving a similar problem as well using XCode 6, This is my project in dropbox. I can't login either. Do you see where i could have gone wrong? https://www.dropbox.com/sh/30khgyz5k1h1vik/AACcOBN8HUdDrprMopIlTWGAa?dl=0

Ben Jakuben
Ben Jakuben
Treehouse Teacher

Some of your code is missing from Dropbox. Can you paste in the code you have for InboxViewController?

I'm having the same problem. Can someone please answer this question?

The app crashes before the Login Screen is shown.

The reason: +[PFInternalUtils assertValidClassForQuery:] + 394 at PFInternalUtils.m:406

Daniel Uili
Daniel Uili
1,940 Points

Same as you mate, anyone able to help, had to start from scratch and d/l getting up to speed project file anyway get error when launching app (0x106c8fac1: jmp 0x106c8facc ; +[PFInternalUtils assertValidClassForQuery:] + 344 at PFInternalUtils.m:412)

Andrew Brotherton
Andrew Brotherton
7,515 Points

I did that and it runs now but i'm still unable to login to the console?

Ben Jakuben
Ben Jakuben
Treehouse Teacher

Can you paste details about your new error in a new thread? Tag me with "[at]Ben Jakuben" to call my attention to it.

Russell Warwick
Russell Warwick
1,601 Points
-(void)viewWillAppear:(BOOL)animated{
    PFUser *currentUser =[PFUser currentUser];
    if (currentUser) {
        NSLog(@"Current User:%@",currentUser);
        [self retrieveMessages];

    }
    else{

        [self performSegueWithIdentifier:@"showLogin" sender:self];


    }


    [super viewWillAppear:animated];

    [self.navigationController.navigationBar setHidden:NO];

}

I had this problem before, i tried this and it worked fine :) it also works buy removing the viewWillAppear method and then running it logging in and then re-add the viewWillAppear method :)

Andrew Brotherton
Andrew Brotherton
7,515 Points

I fixed my problem by replacing the code that was in the signupviewcontroller.m with the code directly from parse for sign.up and I was in there and everything worked like magic.

Daniel Benito
Daniel Benito
4,341 Points

I think I found the cause, but not the solution to this problem.

The problem arose for me when I quit the application after logging out. After doing that I would get the NSInvalidArgumentException that the OP was receiving. Apparently, this happened because the viewWillAppear method on InboxViewController.m was being called despite performing the segue to the login view, and therefore the [self retrieveMessages] function was being called, crashing the app.

To fix this, I commented that line and recompiled the app. After doing that, it will take me to the login screen just fine. After logging in or registering it will take me back to the inbox view. Of course since the retrieveMessages method is commented out, it won't display any messages. At this point you can close the app. Uncomment the [self retrieveMessages]; line and recompile.

Everything works fine as long as you don't quit or close the app while being logged out.

Anyone else found this to work for them?