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 trialNick Barnes
7,818 PointsRibbit 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
42,016 Pointsyes 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
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
Treehouse TeacherCan 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
16,144 PointsI had the same issue, changing the logged user if statement to viewWillAppear fixed the problem for me. Thanks Ben.
Hayden Pennington
6,154 PointsBen's solution worked for me running Xcode 6.3 and IOS 8.3. Thanks!
Andrew Brotherton
7,515 Points 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
9,964 PointsI 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
10,927 Pointshad same issue but solved by your code #Trevor Duersch Thanks
Stone Preston
42,016 Pointsthere 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
7,818 PointsHi 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
7,515 PointsI'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
Treehouse TeacherSome of your code is missing from Dropbox. Can you paste in the code you have for InboxViewController?
Adam Cooper
9,280 PointsI'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
1,940 PointsSame 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
7,515 PointsI did that and it runs now but i'm still unable to login to the console?
Ben Jakuben
Treehouse TeacherCan 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
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
7,515 PointsI 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
4,341 PointsI 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?