Alex McPherson
Alex McPherson

Reputation: 3195

RangeOfString crash on not finding result iOS

I have string from JSON that sometimes looks like this @"2, 18, 27, 29" called mayString. Other times this string will just be @"2" (One number and no comma separation)

I want to test if the string contains the comma using the below code:

NSRange range = [mayString rangeOfString:@","];
        if (range.location != NSNotFound) {
            NSLog (@"Substring found at: %d", range.location);
        }

        else{

            NSLog (@"Substring not found");
        }

It works fine when the string does contain a comma separation but crashes when there isn't a comma I would expect the log to say "Substring not found"? But I get [__NSCFNumber rangeOfString:]: unrecognized selector sent to instance 0x1d533500

Upvotes: 2

Views: 2390

Answers (4)

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726519

Since JSON is untyped, the parser tries to figure out what's inside the string. When the string looks like a number, say, @"2", JSON gives you back an NSNumber object, not an NSString. You can assign it to NSString * variable, and Objective C compiler would not complain, but the value inside would remain NSNumber.

Here is how you can fix it:

id myObject = ... // Instead of MSString *myString

if ([myObject isKindOfClass:[NSNumber class]]) {
        NSLog (@"Object is not a string");
} else if ([myObject isKindOfClass:[NSString class]]) {
    NSRange range = [mayString rangeOfString:@","];
    if (range.location != NSNotFound) {
        NSLog (@"Substring found at: %d", range.location);
    } else{
        NSLog (@"Substring not found");
    }
}

You can also force it into a string, like this:

myString = [myString description]; // Not recommended

Even if myString was NSNumber before the assignment above, it will be an NSString after it, regardless of its initial type. However, keeping the original type is usually a better approach.

Upvotes: 4

Volodymyr B.
Volodymyr B.

Reputation: 3441

If your value in JSON has just one number, NSJSONSerializer always converting it to NSNumber. So your NSString actually NSNumber. You can check it with isKindOfClass:

if([mayString isKindOfClass:[NSNumber class]) {
   // do something
}

EDIT: sorry duplicate answer, my skill of writing not so good

Upvotes: 1

BhushanVU
BhushanVU

Reputation: 3455

try below code...as Marcin is right...

NSRange range = [[NSString stringWithFormat:@"%@",mayString] rangeOfString:@","];
        if (range.location != NSNotFound) {
            NSLog (@"Substring found at: %d", range.location);
        }

        else{

            NSLog (@"Substring not found");
        }

Upvotes: 3

Marcin Kuptel
Marcin Kuptel

Reputation: 2664

It looks like your "string" is actually an instance of NSNumber.

Upvotes: 5

Related Questions