GeekedOut
GeekedOut

Reputation: 17185

iOS - exception when checking if string is empty

I am doing something like this:

// GET THE USER ID
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
NSString *user_id = [standardUserDefaults objectForKey:@"user_id"]; 

And then checking whether the user_id is empty

if ([user_id length] == 0) {
  proceed = false;
  NSLog(@"Error: User id is not set.");
}

And I get this runtime exception:

* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFBoolean length]: unrecognized selector sent to instance 0x1469f70'

Any idea why I get the exception? I didn't think there was anything too wrong with what I was doing.

Thanks!

Upvotes: 0

Views: 2291

Answers (2)

Tommy
Tommy

Reputation: 100632

This:

NSString *user_id = [standardUserDefaults objectForKey:@"user_id"];

Is returning an NSNumber (as NSCFBoolean is a private subclass of NSNumber) rather than a string. It therefore doesn't implement length, causing the exception.

Perhaps you want to test [user_id intValue] > 0? Even if you convert it to a string it'll always have some length.

(side issues raised: merely declaring user_id as a reference to an NSString doesn't mean that anything you assign to it magically becomes a string; indeed there are no type object-type coercion effects whatsoever. The compiler doesn't complain because the NSUserDefaults return objects of type id, i.e. it guarantees they're objects but makes no claims as to their type, and the compiler doesn't know either. All objects may be cast to and from id without generating a warning, so that it can be used by classes such as the user defaults, NSArray, etc, where they can accept anything as long as it's an object).

EDIT: based on issues raised in the comments, it sounds like the thing originally being stored may not be a string. A good way to validate web stuff is probably something like:

// fall through here if the object isn't a string
if(![responseString isKindOfClass:[NSString class]])
{
    // check whether it's something that can be converted to a string
    if(![responseString respondsToSelector:@selector(stringValue)])
    {
        // some sort of error condition; the server returned something
        // that isn't a string and doesn't convert (in and of itself) to string
    }
    else
    {
        // convert the object to a string
        responseString = [responseString stringValue];
    }
}

Upvotes: 5

emu
emu

Reputation: 36

The reason you are getting that error is you are trying to call 'length' on what appears to be a boolean. Either way, for checking if a string is blank here are some easy methods you can add to the NSString class by means of a category:

    -(BOOL)isBlank{
        return [[self trim] length]==0;
    }
    -(NSString *)trim{
        return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet] ];
    }

Then to call it it's just:

    [myString isBlank];

Upvotes: 1

Related Questions