App crash after ' - objective-c

My application is crashing when a ' appears in the title of the JSON code i'm parsing.
This line is loading the title's:
[[cell textLabel] setText:[item objectForKey:#"title"]];
JSON:
NSString *jsonString = [NSString
stringWithContentsOfURL:[NSURL URLWithString:#"**test.php"]
encoding:NSStringEncodingConversionAllowLossy
error:nil];
// Create parser
SBJSON *parser = [[SBJSON alloc] init];
NSDictionary *results = [parser objectWithString:jsonString error:nil];
parser = nil;
// Set tableData
[self setTableData:[results objectForKey:#"items"]];
Crash:
tableData NSArray * 0x00000001
2012-04-10 10:29:11.446 *[21222:f803] -[NSNull isEqualToString:]:
unrecognized selector sent to instance 0x146ace8 2012-04-10
10:29:11.447 *[21222:f803] * Terminating app due to uncaught
exception 'NSInvalidArgumentException', reason: '-[NSNull
isEqualToString:]: unrecognized selector sent to instance 0x146ace8'
* First throw call stack: (0x13d4022 0x1565cd6 0x13d5cbd 0x133aed0 0x133acb2 0x15e0ff 0x2b10 0xb8c54 0xb93ce 0xa4cbd 0xb36f1 0x5cd21
0x13d5e42 0x1d8c679 0x1d96579 0x1d1b4f7 0x1d1d3f6 0x1db81ce 0x1db8003
0x13a8936 0x13a83d7 0x130b790 0x130ad84 0x130ac9b 0x12bd7d8 0x12bd88a
0x1e626 0x1ded 0x1d55) terminate called throwing an exception(lldb)

The key part of that crash info is: unrecognized selector sent to instance ... [NSNull isEqualToString:]
It looks like your JSON contains null somewhere that you are expecting a string. Later on, probably inside of setTableData: you will be doing something like this:
NSString* whatever = [items objectForKey:#"whatever"];
if([whatever isEqualToString:#"hello"]){
...
}
And that will crash, because the whatever variable contains NSNull, not an NSString like you were expecting.

Related

Replacing stuff in JSON string

Why do I get an error with this:
NSString *jsonString = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSLog(#"jsonRoster unmasked: %#", jsonString);
NSString *maskedString = [self maskJSON:jsonString withMultipleElementStartString:#"###multipleElementsBegin###" andMultipleEndString:#"###multipleElementsEnd###" andSingleElementStartString:#"###elementBegin###" andSingleElementEndString:#"###elementEnd###"];
NSLog(#"jsonRoster masked: %#", maskedString);
Here is the error:
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[__NSDictionaryI
stringByReplacingOccurrencesOfString:withString:]: unrecognized
selector sent to instance 0x600002932400'
But why, is the string still a Dictionary?
As per error message JSONObjectWithData returned an NSDictionary object, in fact it is in practice so, JSONObjectWithData returns a dictionary or an array depending on your JSON structure. So you should normally check return type and handle it properly.
Edit
To get an NSString you can use its initWithData:encoding: method.

How do I access this JSON-encoded value in Objective C?

I have an object that looks like this:
{
"userID": "2A8761E4-C13A-470E-A759-91432D61B6AF-25982-0000352D853511AF"
}
It is the return value from from an AFNetworking JSON request. The object is called JSON.
I've tried to access the userID value several different ways but keep getting the error "Unrecognized selector". Here's what I've tried:
[JSON objectForKey:#"userID"]
[JSON valueForKey:#"userID"]
[[JSON objectAtIndex:0] valueForKey:#"userID"];
[[JSON objectAtIndex:0] objectForKey:#"userID"];
[JSON objectAtIndex[0]];
What is the correct syntax?
EDIT
Here's more detail on the Unrecognized Selector error.
-[__NSCFString objectForKey:]: unrecognized selector sent to instance 0x20068150
2013-02-23 15:58:13.993 BMTabbed[12312:907] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString objectForKey:]: unrecognized selector sent to instance 0x20068150'
*** First throw call stack:
(0x325032a3 0x3a22097f 0x32506e07 0x32505531 0x3245cf68 0xbe9ed 0xbe91b 0xaae8f 0xabe65 0x3a63811f 0x3a6374b7 0x3a63c1bd 0x324d6f3b 0x32449ebd 0x32449d49 0x360202eb 0x3435f301 0x96e95 0x3a657b20)
libc++abi.dylib: terminate called throwing an exception
If
NSLog(#"%#", [JSON class]); //=> __NSCFDictionary
then either
[JSON objectForKey:#"userID"]
or
JSON[#"userID"]
should work.
You are sending NSDictionary selectors to an NSString. You can use NSJSONSerialization to convert a JSON string to an NSDictionary or NSArray, depending on the root object of your JSON string. In your case it is an NSDictionary:
NSData *data = [NSData dataWithBytes:[json UTF8String] length:[json lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];

How to parse this JSON response into a key & value pairs array

there are a lot of questions like this and i'm experienced with json format too but i couldnt parse the response below(at the bottom):
I'm using NSJSONSerialization for parsing the response into NSDictionary but the it gives the error like below:
My code:
NSString *subURL= sharedDa.ip;
NSData *data=[NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:#"http://192.168.69.230/tsadmin.php?tssearch=%#", subURL]]];
NSError *error=nil;
NSDictionary* portsResult=[NSJSONSerialization JSONObjectWithData:data options:
NSJSONReadingMutableContainers error:&error];
NSDictionary * tempPorts;
NSString *k;
for(k in [portsResult allKeys]){
tempPorts = [portsResult objectForKey:k];
NSLog(#"Temporary ports: %#", tempPorts);
}
And the error code is below:
2012-09-28 18:47:37.508 BNTPRO ST Manager[2609:fb03] -[__NSArrayM allKeys]: unrecognized selector sent to instance 0x6b83ed0
2012-09-28 18:47:37.511 BNTPRO ST Manager[2609:fb03] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM allKeys]: unrecognized selector sent to instance 0x6b83ed0'
*** First throw call stack:
(0x1568022 0x1b20cd6 0x1569cbd 0x14ceed0 0x14cecb2 0x57cd 0x28fa1e 0x28fd11 0x2a18fd 0x2a1aef 0x2a1dbb 0x2a285f 0x2a2e06 0x2a2a24 0x3e59 0x2595c5 0x2597fa 0xaee85d 0x153c936 0x153c3d7 0x149f790 0x149ed84 0x149ec9b 0x245a7d8 0x245a88a 0x1c8626 0x26d2 0x2645 0x1)
terminate called throwing an exception(lldb)
now my data snippet is: [{"k1":{"v":"0"}},{"k2":{"v":"0"}},{"k3":{"v":"0"}},{"k4":{"v":"0"}},{"k5":{"v":"0"}},{"k6":{"v":"0"}},{"k7":{"v":"1"}},{"k8":{"v":"0"}},{"k9":{"v":"1"}},{"k10":{"v":"0"}},{"k11":{"v":"1"}},{"k12":{"v":"0"}},{"k13":{"v":"1"}},{"k14":{"v":"0"}},{"k15":{"v":"0"}},{"k16":{"v":"0"}}]
but it still gives the same error.. even i decşare the iVar as NSDictionary why does it complain of nsmutable array??
The JSON you're parsing is an array, not an object. So the result of [NSJSONSerialization JSONObjectWithData...] is not an NSDictionary *, but an NSArray * instead.
For example, for the JSON data
[{"k1":{"v":"0"}}, {"k2":{"v":"0"}}]
You can use something similar to this code (don't have xcode right now to try to run it):
NSArray * arr = [NSJSONSerialization JSONObjectWithData:data options:...];
int i;
for (i = 0; i < [arr count]; i++) {
NSDictionary * dic = [arr objectAtIndex:i];
NSString * k;
for (k in [dic allKeys]) {
NSLog(#"Temporary ports: %#", [dic objectForKey:k]);
}
}

Error in NSMutableArray

I am very new to ios development, I am trying to add some values from NSMutableDictionary to NSMutableArray, when I run the code I get this error
2012-05-29 14:09:34.913 iShop[7464:f803] -[__NSCFArray objectForKey:]:
unrecognized selector sent to instance 0x6e423d0 2012-05-29
14:09:34.915 iShop[7464:f803] * Terminating app due to uncaught
exception 'NSInvalidArgumentException', reason: '-[__NSCFArray
objectForKey:]: unrecognized selector sent to instance 0x6e423d0'
* First throw call stack: (0x13cb022 0x155ccd6 0x13cccbd 0x1331ed0 0x1331cb2 0x2bb7 0x13cce42 0x93b9df 0x139f94f 0x1302b43 0x1302424
0x1301d84 0x1301c9b 0x12b47d8 0x12b488a 0x15626 0x28bd 0x2825)
terminate called throwing an exception(lldb)
below is my code:
-(void) getData:(NSData *) response {
NSError *error;
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:response options:kNilOptions error:&error];
//NSLog(#"%#", json);
jsonArray = [[NSMutableArray alloc] init];
jsonArray = [json objectForKey:#"Name"];
NSLog(#"%#", jsonArray);
}
- (void)viewDidLoad {
[super viewDidLoad];
jsonURL = [NSURL URLWithString:#"http://localhost:8888/read_product_list.php"];
dispatch_async(BgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL:jsonURL];
[self performSelectorOnMainThread:#selector(getData:)
withObject:data waitUntilDone:YES];
});
}
JSONObjectWithData return an object of type id. depending on the structure of your received json data.
The data recieved is eiher NSDictionary or NSArray. In your case I am guessing the top level object is of type NSArray which does not respond to objectForKey

Hpple implementation/Unrecognized selector

I am working with the hpple html parser here: https://github.com/topfunky/hpple
To test the function I've added it to a simple project and am able to compile and open the simulator without errors, but when it is called, I get an unrecognized selector error.
//THIS ACTION SET TO RUN WITH THE PUSH OF A BUTTON
- (IBAction)parseElements{
NSString *urlRequest = item.link;
NSLog(#"urlRequest defined.");
NSData *htmlData = [NSString stringWithContentsOfURL:[NSURL URLWithString: urlRequest] encoding:NSUTF8StringEncoding error:nil];
NSLog(#"htmlData created.");
TFHpple *xpathParser = [[TFHpple alloc] initWithHTMLData:htmlData];
NSLog(#"xpathParser made.");
NSString *queriedItem = #"[#class='title']";
// THE APP FAILS WHILE TRYING TO EXECUTE THE NEXT LINE
NSArray *elements = [xpathParser searchWithXPathQuery:queriedItem];
NSLog(#"elements searched.");
TFHppleElement *element = [elements objectAtIndex:0];
NSLog(#"element recalled.");
NSString *storyTitle = [element content];
NSLog(#"The title of the story is: %#", storyTitle);
}
The NSLogs manage to display through "xpathParser made" and then I receive this unrecognized selector message:
-[__NSCFString bytes]: unrecognized selector sent to instance 0x6a52d60
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString bytes]: unrecognized selector sent to instance 0x6a52d60'
* First throw call stack:
(0x16c8052 0x1859d0a 0x16c9ced 0x162ef00 0x162ece2 0x495c 0x352e 0x2e3f 0x16c9ec9 0x1395c2 0x13955a 0x1deb76 0x1df03f 0x1de2fe 0x15ea30 0x15ec56 0x145384 0x138aa9 0x15b2fa9 0x169c1c5 0x1601022 0x15ff90a 0x15fedb4 0x15feccb 0x15b1879 0x15b193e 0x136a9b 0x2658 0x25b5)
terminate called throwing an exception
I understand it doesn't like SOMETHING, but what is causing the glitch or are additional frameworks/imports necessary for proper execution? As it stands I have UIKit, viewcontroller.h and TFHpple.h set as the only imports in that file.
Here's your problem:
NSData *htmlData = [NSString stringWithContentsOfURL:[NSURL URLWithString: urlRequest] encoding:NSUTF8StringEncoding error:nil];
TFHpple *xpathParser = [[TFHpple alloc] initWithHTMLData:htmlData];
TFHpple's initWithHTMLData is supposed to take an NSData. You declare htmlData to be an NSData, but the actual object you're assigning to it is an NSString.
This should fix it:
NSData *htmlData = [NSData dataWithContentsOfURL:[NSURL URLWithString: urlRequest]];