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

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:-)

Related

[NSTaggedPointerString stringValue]: unrecognised selector sent to instance in NSString comparision?

I got this error [NSTaggedPointerString stringValue]: unrecognised selector sent to instance
when I try to check NSString comparison
My code is:
if ([[[dict objectForKey:#"login"] stringValue] isEqualToString:#"1"])
{
}
Please read the error. It clearly states that the value for key login is (already) a string
if ([[dict objectForKey:#"login"] isEqualToString:#"1"])
{
}
or with more convenient key subscription syntax (available for many, many years)
if ([dic[#"login"] isEqualToString:#"1"])
{
}
The object is already a string, so you don't need to use the stringValue selector:
if ([[dict objectForKey:#"login"] isEqualToString:#"1"])
{
}
Note: comparing this with "1" is dodgy; convert it to NSNumber if it's a number.

App crash - when installed from App store but not locally

When i test my app as DEBUG then it works. But when i release to App store and from App Store install the app then it crash.
Therefore i changed the DEBUG RUN method into RELEASE run method for testing.
When i now run as RELEASE run method, then the app crash too (same as APP store Crash). The app crash is pointing at line 19.
How do i fix it? here i am telling to make an DNS (A or AAAA record) self.server = [self.server stringByAppendingString:#".example.com"]; by joining one string with the string i have from line 18.
- (void)myMethodHere:(NSString *)a {
//where a = #"splitme://test1/test2/test3";
NSArray *work_array = [a componentsSeparatedByString:#"splitme://"];
self.use_url =[work_array objectAtIndex:1];
if ([self.use_url length] > 0) {
NSArray *work_array = [self.use_url componentsSeparatedByString:#"/"];
self.server = [work_array objectAtIndex:0];
// -------------------
// CRASH HERE // CRASH HERE
// -------------------
if([self.server length] > 0) {
NSLog(#"!!!!!!!!!!!!!!!!!!!!!! 4 - part 1: %#", self.server); // WORKS
// Here we go CRASHing...
self.server = [self.server stringByAppendingString:#".example.com"];
NSLog(#"!!!!!!!!!!!!!!!!!!!!!! 4 - part 2: %#", self.server); // CRASH CRASH
}
else {
self.server = #"test.example.com";
}
}
else {
NSLog(#"!!!!!!!!!!!!!!!!!!!!!! 9: %#", self.use_url);
}
[self load_later];
}
EDIT 1: Following way of doing let me pass but if i have again self.server outside of this scope then app crash again.
NSString *part1 = self.server;
NSString *part2 = #".example.com";
NSString *result =[part1 stringByAppendingString:part2];
self.server = result;
NSLog(#"!!!!!!!!!!!!!!!!!!!!!! 4 - part 2: %#", self.server);
EDIT 2: crashing on AppDelegate.m, after commenting out the NSLog lines.
2017-04-08 10:32:01.773648+0200 app[344:18271] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles
2017-04-08 10:32:01.774146+0200 app[344:18271] [MC] Reading from public effective user settings.
2017-04-08 10:32:01.778647+0200 app[344:18271] -[__NSArrayM length]: unrecognized selector sent to instance 0x1740457c0
2017-04-08 10:32:01.778888+0200 app[344:18271] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM length]: unrecognized selector sent to instance 0x1740457c0'
*** First throw call stack:
(0x18a956fd8 0x1893b8538 0x18a95def4 0x18a95af4c 0x18a856d2c 0x100006f78 0x1000076e8 0x1000066cc 0x190a85f9c 0x190a85b78 0x190a8c3f8 0x190a89894 0x190afb2fc 0x190d038b4 0x190d092a8 0x190d1dde0 0x190d0653c 0x18c4ff884 0x18c4ff6f0 0x18c4ffaa0 0x18a905424 0x18a904d94 0x18a9029a0 0x18a832d94 0x190af045c 0x190aeb130 0x100007d78 0x18984159c)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
EDIT 3: Crashing NSString not NSString even with explicit cast
- (void)setServer:(NSString *)value
{
if (value != nil && ![value isKindOfClass:[NSString class]]) {
NSLog(#"!!!!!!!!!!!lol!!!!!!!!!!!!! Bug! Set breakpoint here!");
}
self.server = value;
}
NSArray *work_array = [self.use_url componentsSeparatedByString:#"/"];
NSString *setServerURL =(NSString *) [work_array objectAtIndex:0];
[self setServer:setServerURL];
EDIT 4: Crashing
- (void)myMethodHere:(NSString *)a {
NSArray *work_array = [a componentsSeparatedByString:#"test://"];
id objectOne = [work_array objectAtIndex:1];
if ([objectOne isKindOfClass:[NSString class] ] ) {
NSString *objectOneIntoString = objectOne;
self.use_url = (NSString *) objectOneIntoString;
}
if ([self.use_url length] > 0) {
NSLog(#"3: %#", self.use_url);
NSArray *work_array = [self.use_url componentsSeparatedByString:#"/"];
id objectTwo = [work_array objectAtIndex:0];
if ([objectTwo isKindOfClass:[NSString class] ]) {
NSString *objectTwoIntoString = objectTwo;
self.server = objectTwoIntoString;
}
if([self.server length] > 0) {
NSLog(#"4 - part 1: %#", self.server);
NSString *part1 = self.server;
NSString *part2 = #".example.com";
NSString *result = (NSString *) [part1 stringByAppendingString:part2];
self.server = result;
NSLog(#"4 - part 2: %#", self.server);
}
else {
self.server = #"dns.example.com";
NSLog(#"5:%#", self.server);
}
NSLog(#"8: %#", self.server);
}
else {
NSLog(#"9: %#", self.use_url);
}
NSLog(#"10: %#", self.use_url);
}
The error message in your pastebin is:
2017-04-08 10:32:01.778647+0200 app[344:18271] -[__NSArrayM length]: unrecognized selector sent to instance 0x1740457c0
2017-04-08 10:32:01.778888+0200 app[344:18271] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM length]: unrecognized selector sent to instance 0x1740457c0'
This tells you that there was an array on which you called length. So if it really is related to your server property then you are accidentally storing an NSArray there somewhere.
Here's an idea on how to catch that: implement the setServer: method and check whether the type is correct.
- (void)setServer:(NSString *)value
{
if (value != nil && ![value isKindOfClass:[NSString class]]) {
NSLog(#"Bug! Set breakpoint here!");
}
_server = value;
}
Edit: You implemented your setter incorrectly and would normally have produced an endless recursion. So let's start from scratch:
I assume you have a property defined like this:
#property (strong) NSString * server; // Or maybe "copy"
If your property does not look like this you need to tell us!
Then you implement the setter exactly like this:
- (void)setServer:(NSString *)value
{
if (value != nil && ![value isKindOfClass:[NSString class]]) {
NSLog(#"Bug! Set breakpoint here!");
}
_server = value;
// DO NOT DO self.server = value HERE!
}
Then you can just do self.server = blabla; in the rest of your code and if your code sets something that is not a string the NSLog will be hit. So set a breakpoint there!
Edit 2:
Now I've seen in another comment of yours what's wrong…
#property (assign, nonatomic) NSString *server;
The assign does not retain the object! You need to use strong or (in the case if NSString *) copy. As it is, the following will happen:
You assign an object to server.
Since it is not retained, the object is deallocated soon.
But server still has a pointer to that memory location.
Two things can happen now:
Either a new, different object is created at memory location before you access the property. You now get an unexpected object back. Calling methods on this object may work or it may crash since the object does not know the method.
Or the memory location is deemed invalid and you get a crash right away.
Never use assign with objects!
-[__NSArrayM length]: unrecognized selector sent to instance 0x1740457c0
self.server class is NSArray .must string length

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

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

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);

iOS: Getting a strange error ever since I switch header requests library. -[__NSCFString objectForKey:]:

I am getting the error -[__NSCFString objectForKey:]: ever since I switched header request library to AFNetWorking. This is the code that is causing the error.
- (void) syncContentsFinish : (id) result
{
Content *content;
NSArray *contentsArray = [result objectForKey:#"content"];
for ( id object in contentsArray ) {
content = [Content getContentWithDictionary:object];
}
Specifically the content = method is causing this error. Here is the results I am getting from the server.
{
content = {
count = 0;
id = 42488267526162;
};
message = success;
responseCode = 200;
}
I have no idea what is causing this at all but any tips or suggestions are appreciated, also if you need me to post more code (such as the handler that is retrieving the data or the Content class please let me know.
Edit: Actually this is misleading. In the Content class this is what I have that is actually causing the App to crash.
+ (Content *) getContentWithDictionary : (NSDictionary *) dic
{
Content *content = [[Content alloc] init];
if ( [dic objectForKey:#"id"] != [NSNull null] ) {
content.contentId = [[dic objectForKey:#"id"] longLongValue];
}
Its look like Content is NSString not NSDictionary.
results is a dictionary, that much is correct. But the value of the "content" key is not an array, but another dictionary. Therefore, your for loop is actually iterating the keys of the dictionary. This means that each object is an NSString.

Resources