iOS - Why does this NSString comparison blow-up? [duplicate] - ios

This question already has an answer here:
Unrecognized selector error for isEqualToString: when setting text of a label
(1 answer)
Closed 8 years ago.
I have looked at SO for similar questions, but am open to being pointed to a duplicate.
I am receiving some JSON from a site, and I want to test for a 404 response.
I have this expression:
NSString *responseString = [json objectForKey:#"statusCode"];
NSLog(#"responseString: %#", responseString);
NSString *myString1 = #"404";
NSLog(#"%d", (responseString == myString1)); //0
NSLog(#"%d", [responseString isEqual:myString1]); //0
NSLog(#"%d", [responseString isEqualToString:myString1]); //Crash
The response string returns 404.
The first and second logs result in 0, and the 3rd crashes with this log:
[__NSCFNumber isEqualToString:]: unrecognized selector sent to instance 0xb000000000001943
2015-01-29 16:23:33.302 Metro[19057:5064427] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber isEqualToString:]: unrecognized selector sent to instance 0xb000000000001943'

statusCode is a number, not a string. The error makes this clear by telling you that you are trying to call isEqualToString on an NSNumber.
Try this:
NSInteger responseCode = [json[#"statusCode"] integerValue];
NSInteger notFoundCode = 404;
if (responseCode == notFoundCode) {
// process 404 error
}

The fact that you declared responseString as an NSString does not guarantee that [json objectForKey:#"statusCode"] will indeed return an NSString object.
Actually, the JSON parser detected an integer in your JSON data, and as such, returned an NSNumber. So you should be able to test it against a plain 404 literal using integerValue or, if you want to keep working with strings, will need to convert it first with stringValue.
Anyway, try this, it should return 1:
NSNumber *response = [json objectForKey:#"statusCode"];
...
NSLog(#"%d", [response integerValue] == 404);

Related

Why does Length not work on a NSString?

I am trying to check the length of string, but I get unrecognized selector when the code is executed and hits the IF statement.
THE VALUE IN THE DICTIONARY IS A STRING.
NSString * checkString = [myDictionary objectForKey:#"somekey"];
NSLog(#"length: %lu", (unsigned long)[checkString length]);
if([checkString length] > 0){
}
ERROR From console:
length: 0
[__NSCFNumber length]: unrecognized selector sent to instance
For simplicity:
NSString * checkString = #"my string"; //[myDictionary objectForKey:#"somekey"];
NSLog(#"length: %lu", (unsigned long)[checkString length]);
if([checkString length] > 0){
}
length: 9
[__NSCFNumber length]: unrecognized selector sent to
instance
Why?
The error says that your instance is not a NSString but a NSNumber. That's probably because you stored a NSNumber in [myDictionary objectForKey:#"somekey"].
Try to put [yourValueThatYouThinkItsAString stringValue] in the place where you store this value.
I tried your code and I'm not getting error with it (with #"my string" value).
What you can try :
NSString *checkString = [[myDictionary objectForKey:#"somekey"] stringValue];
NSLog(#"length: %lu", (unsigned long)[checkString length]);
if([checkString length] > 0){
}
PS : in your NSLog() you've got a additional argument, remove it.
The reason the length is not working on NSString* is that it's not NSString*. Despite the cast, which Objective-C cannot verify, the object in your dictionary is NSNumber*, not NSString*. That is why the code compiles, but fails to run.
[myDictionary objectForKey:#"somekey"] call returns id, a generic object reference. That is why Objective-C must trust you when you perform a cast to NSString* that the object at "somekey" is actually a string.
It does not fail in NSLog because you made a mistake that prevents the length from being evaluated. Change NSLog to see it fail:
NSLog(#"length: %lu", (unsigned long)[checkString length]);
If you have XCode 7 or newer, you can use lightweight generics to help Objective-C with type checking. You can specify object types for keys and values in your dictionary, so that the compiler could catch invalid casts for you:
NSDictionary<NSString*,NSString*> *myDictionary = ...

[NSNull length]: unrecognized selector sent to instance in objective-c [duplicate]

This question already has answers here:
[NSNull isEqualToString:]
(7 answers)
Closed 6 years ago.
I am getting some JSON data from a service, one property is a string to represent an image url, it seems what is returned is NULL, I do the check but XCode breaks before my if statement and generate an exception. this is my code below:
- (void)configureCellForAlbum:(Album *)album {
self.albumTitle.text = album.albumTitle;
self.artisteName.text = album.artisteName;
NSURL *imageUrl = [NSURL URLWithString:album.thumbnail];
if (imageUrl == nil) {
self.albumThumbnail.image = [UIImage imageNamed:#"music_record"];
}
else {
self.albumThumbnail.imageURL = imageUrl;
}
}
the exception is
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSNull length]: unrecognized selector sent to instance.
How do I do the check so that if the value retured is null, it uses a local image but if not null to use the image string url that is returned?
nil is returned by the dictionary if no object with that key was found.
An instance of NSNull is inserted by the JSON parser to indicate that a null-valued key was present.
You need to check whether the object you got back was really a string. You are failing to catch the case where there is an object but it is not a string.
E.g.
if ([albm.thumbnail isKindOfClass:[NSString class]])
... a string-form URL is present ...
else
.... something else, or nothing, was found; use a fallback ...
I tried from other question which asked same that what you ask here.But you need to customize the code like above Tommy's code.
NSDictionary *dict = [[NSDictionary alloc]initWithObjectsAndKeys:#"iOS",#"language",nil];
id Value = [dict objectForKey:#"language"];
NSString *strLanguage = #"";
if (Value != [NSNull null]) {
strLanguage = (NSString *)Value;
NSLog(#"The strLanguage is - %#", strLanguage);
}
Output
The strLanguage is - iOS
Thank You nhgrif:-)

NSCFNumber escapedString Error with a NSDictionary

So I'm getting this error when creating a NSDictionary:
DLog(#"hiliteID: %# | regionID: %#", hiliteID, regionID);
if ([hiliteID isKindOfClass:[NSNumber class]]) {
DLog(#"hititeID is a number");
}
if ([hiliteID isKindOfClass:[NSString class]]) {
DLog(#"hiliteID is a string");
}
if ([regionID isKindOfClass:[NSNumber class]]) {
DLog(#"regionID is a number");
}
if ([regionID isKindOfClass:[NSString class]]) {
DLog(#"regionID is a string");
}
NSDictionary *regionDictionary = [NSDictionary dictionaryWithObject:regionID forKey:hiliteID];
DLog(#"regionDictionary: %#", regionDictionary);
id result = [self.serverCall XMLRPCCall:kSaveHilitedObjects withObjects:#[self.mapContext, regionDictionary]];
What is logged:
DEBUG | hiliteID: 160399 | regionID: 950
DEBUG | hititeID is a number
DEBUG | regionID is a number
DEBUG | regionDictionary: {
160399 = 950;
}
DEBUG -[__NSCFNumber escapedString]: unrecognized selector sent to instance 0x7947f5d0
DEBUG *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber escapedString]: unrecognized selector sent to instance 0x7947f5d0'
0x7947f5d0 has a value of 160399 so it is hiliteID.
hiliteID is a returned value from our server and is set as a NSString. I cast it to a NSNumber:
NSArray *hiliteIDs = [result allKeys];
if ([[hiliteIDs firstObject] isKindOfClass:[NSString class]]) {
return [NSNumber numberWithInteger:[[hiliteIDs firstObject] integerValue]];
}
else if ([[hiliteIDs firstObject] isKindOfClass:[NSNumber class]]) {
return [hiliteIDs firstObject];
}
As far as I know, there is no issue with what I am doing here.
the line:
id result = [self.serverCall XMLRPCCall:kSaveHilitedObjects withObjects:#[self.mapContext, regionDictionary]];
I've used this class dozens of times in the code and never had an issue.
What can be causing the error?
reason: '-[__NSCFNumber escapedString]: unrecognized selector sent to instance 0x7947f5d0'
Someone trying to call -escapedString method from NSNumber class, so it seems like the problem is that you passing NSNumber argument when NSString required. Try to use only NSString values inside your NSDictionary.
Whatever XMLRPCCall:withObjects: is calling an invalid method. I would recommend making all inputs into this method into NSStrings so that that call doesn't internally call methods on NSNumbers that NSNumber isn't capable of responding to.
NSString *regionIDString = [regionID stringValue];
NSString *hiliteIDString = [hiliteID stringValue];
NSDictionary *regionDictionary = [NSDictionary dictionaryWithObject:regionIDString forKey:hiliteIDString];

Get JSON value from NSDictionary and place in NSString not working

In my previous app I had this code to extract JSON from an NSDictionary variable into a string:
NSString *task_id = [jsonString objectForKey:#"key"];
It worked very well but for some reason it won't work in my new app anymore? Instead I get this error:
-[__NSCFString objectForKey:]: unrecognized selector sent to instance 0x14d7bda0
Does anyone know why this might not work?
Peter
Make sure that the jsonString is NSDictionary:
if([jsonString isKindOfClass:[NSDictionary class]]) {
NSString *task_id = [jsonString objectForKey:#"key"];
} else {
// is not a dictionary
NSLog(#"%#", jsonString);
}

ios - get values from NSDictionary

I have JSON on my server, which is parsed into iOS app to NSDictionary. NSDictionary looks like this:
(
{
text = Aaa;
title = 1;
},
{
text = Bbb;
title = 2;
}
)
My question is - how to get just text from first dimension, so it should be "Aaa". I've tried to use this:
[[[json allValues]objectAtIndex:0]objectAtIndex:0];
But it didn't work, it ends with error
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[__NSCFArray allValues]:
unrecognized selector sent to instance 0x714a050'
So can you help me please, how to get just one value from specified index? Thanks!
That error message is simply telling you that NSDictionary (which is the first object of that array, along with the second) doesn't respond to objectAtIndex.
This will be a bit cody, but it explains it better:
NSArray *jsonArray = [json allValues];
NSDictionary *firstObjectDict = [jsonArray objectAtIndex:0];
NSString *myValue = [firstObjectDict valueForKey:#"text"];
Your JSON object is an array, containing two dictionaries. That's how to get the values:
NSDictionary* dict1= json[0];
NSString* text= dict1[#"text"];
NSString* title= dict1[#"title"];
Try this:
NSString *txt = [[json objectAtIndex:0] objectForKey:#"text"];
UPDATE: Have fixed the error. Thanks yunas.

Resources