NSJSONSerialization returning nil - iphone

{"User":{"id":"42","name":"martin"}}
Converting my NSData to NSString returns this JSON which seems completely valid, however the method:
[NSJSONSerialization isValidJSONObject:data]
is saying this is not a valid JSON object.
Could anyone point out a mistake I have made or think of a reason why this is happening?

I bet there is a non-printable character in your string for example, making the data invalid.
Declare an NSError* error variable then call [NSJSONSerialization JSONObjectWithData:data options:0 error:&error] method to try to convert the JSON: obviously if your data is considered invalid, it will return nil, but at least you will have the description of what's wrong in the NSError* error variable after that.
NSData* data = ... // your data
NSError* error = nil; // Declare a variable to hold the error upon return
id obj = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; // Try to convert your data
NSLog(#"obj: %# ; error: %#", error); // Log the decoded object, and the error if any

Related

Ok in simulator but throwing exception in ios device

when i am running my app in the simulator everything is working perfectly .But when i running the same app in the Ipad exception is being thrown.
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'data parameter is nil.
In my app at one step i have to request a web-URl and need to parsed the returned JSON response. But I have checked the web-url and have been able to parse perfectly in simulator. But all the problem has been arisen in real ios device.But I think i have identified the code where it is getting wrong.
+ (NSDictionary*) getParsedJSON:(NSString*) urlString {
NSLog(#"################################################################################");
NSLog(#"getParsedJSON => urlString:");
NSLog(#"%#", urlString);
NSURL* url = [NSURL URLWithString:urlString];
NSURLRequest* request = [NSURLRequest requestWithURL:url];
NSURLResponse *response1 = nil;
NSError *error = nil;
NSData* response = [NSURLConnection sendSynchronousRequest:request returningResponse:&response1 error:&error];
//NSData* response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSLog(#"--------------------------------------------------------------------------------");
NSString* responseString = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSLog(#"getParsedJSON => responseString:\n%#", responseString);
NSLog(#"--------------------------------------------------------------------------------");
NSError* jsonParsingError = nil;
NSDictionary* parsedJSON = [NSJSONSerialization JSONObjectWithData:response options:0 error:&jsonParsingError]; // here is place where exception seems to be thrown.
if (jsonParsingError) {
NSLog(#"ERROR in parsing JSON: %#", jsonParsingError);
} else {
NSLog(#"getParsedJSON => parsedJSON: \n%#", [parsedJSON description]);
}
NSLog(#"################################################################################");
return parsedJSON;
}
I have identified the line where it seems to be wrong .I have also attached screen shot of the exception report..Hoping for your experienced reply.
AS we can see from the logs your response string is null while you are using it on your Device. This may be due to some internet access problem. Try to Use:
if([response isequaltostring:#"(null)"]||response == nil || response.length == 0)
{
NSError* jsonParsingError = nil;
NSDictionary* parsedJSON = [NSJSONSerialization JSONObjectWithData:response options:0 error:&jsonParsingError]; // here is place where exception seems to be thrown.
if (jsonParsingError) {
NSLog(#"ERROR in parsing JSON: %#", jsonParsingError);
}
else {
NSLog(#"getParsedJSON => parsedJSON: \n%#", [parsedJSON description]);
}
}
Also try to add the exceptional breakpoint and post where exactly the app crashed.
Let me know the result.
First, you need to set an exception breakpoint in Xcode - there are many posts here on how to do that. Second, after each of you statements where an object is created or returned, add an assert:
NSURL *foo = ...
assert(foo);
Doing this will help you find the first issue not the last one.
As per your logs, your response string is empty!
Do the below two things!
Add NSLog(#"Response Data: %#",response); and check if the response has value?
If 'response' has value, convert it to a string - Log the string value - And check if the any of the key has nil value?
'NSJSONSerialization JSONObjectWithData' method would crash if it finds any key with nil value.

Problems with JSON on iOS

I'm trying to parse the JSON file at this URL: http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20yahoo.finance.quotes%20where%20symbol%20in%20(%22YHOO%22%2C%22AAPL%22%2C%22GOOG%22%2C%22MSFT%22)%0A%09%09&format=json&diagnostics=true&env=http%3A%2F%2Fdatatables.org%2Falltables.env&callback=results
The code that I have so far is as follows:
NSData *data=[NSData dataWithContentsOfURL:[[NSURL alloc] initWithString:url]];
NSError *error = nil;
id myJSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
NSLog(#"%#", error);
NSArray *jsonArray = (NSArray *)myJSON;
for (id element in jsonArray) {
NSLog(#"Element: %#", [element description]);
}
This code seems to come up with an error each time (ERROR 3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.)").
I'm wondering if this is a problem with the way that I'm downloading/parsing the data or if it's a problem within the actual JSON in which I have to approach it in a different matter.
Remove the &callback=results at the end of the URL. This causes the JSON to not start with an array or dictionary. Just be aware that if you are referencing "results" in your JSON code then you will need to remove/change that. If you diff the two JSON texts then you will see the difference (look at the beginning).
in a web browser open the result of the url you posted copy the contents then go to jsonlint.com and paste the contents then click validate. it shows you that the input is not valid json so you might have to do some additional parsing.

iOS - How to print value in textfield using delegate

I am new to iOS. I have some problem do you have some solution for it? I am not able to print the json value in textfield
This is my contactViewController.m file:
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
fname.text=#"Hello";
}
After the view is loaded hello value is shown in the text box, but when I call list button to get the json values:
-(IBAction)list:(id)sender{
vedant=[[WebserviceViewController alloc]init];
[vedant listContacts];
}
Then from webserviceViewController.m I pass the jsonResponse to the same file i.e contactViewController.m and parse the json value and print it but it does not shows the value in text field
-(void)allContacts:(NSString *)JSONResponse{
NSLog(#"%#",JSONResponse);
NSData *jsonData = [JSONResponse dataUsingEncoding:NSASCIIStringEncoding];
//
NSError *err;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&err];
int accCount =[json count];
for(int i=0;i<accCount;i++){
NSData *jsonData = [JSONResponse dataUsingEncoding:NSASCIIStringEncoding];
//
// NSLog(#"%#",JSONResponse);
NSError *err;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&err];
NSString *firstName = [NSString stringWithFormat:#"%#", [[json objectAtIndex:i] objectForKey:#"first_name"]];
NSLog(#"%#",firstName); //this prints the actual first name in console But
fname.text=firstName;
NSLog(#"%#",fname.text); //it prints "(Null)" in console
}
}
Do I need to create delegate to pass value?
Yes, then any help of creating such delegate some article or example.
Check if fname isn't nil. If you forgot to properly connect it in Interface Builder, fname will be nil and all messages sent to it (like setText:) will be ignored.
Please First check that you have bind your textfield with your fname variable. If yes then try to assign value using this:
fname.text=[NSString stringWithFormat:#"%#",firstName];
Just try this. I hope this will work for you.
Get your first name(i.e value from json) into global value and assign that global value into your textfield . It is so simple. if you still have doubts than reply i'll post sample code
txtName.text=firstname; OR
txtName.text=[NSString stringWithFormat:#"%#",firstName];
Using Delegate i solved this problems
In my contactViewController.m file:
-(IBAction)list:(id)sender{
vedant=[[WebserviceViewController alloc]init];
vedant.delegate=self;
[vedant listContacts];
}
In webserviceViewController.h I created my own delegate
#protocol WebservicesDelegate <NSObject>
-(void)allContacts:(NSString *)JSONResponse;
#end
then in webserviceViewController.m file after getting the json response from backend i am sending the response back to my contactViewController.m file using this code
[self.delegate allContacts:jsonResponse];
the compiler comes back to allContacts function in contactViewController.m file this code is same i didn't change the code now it prints the value.
-(void)allContacts:(NSString *)JSONResponse{
NSLog(#"%#",JSONResponse);
NSData *jsonData = [JSONResponse dataUsingEncoding:NSASCIIStringEncoding];
//
NSError *err;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&err];
int accCount =[json count];
for(int i=0;i<accCount;i++){
NSData *jsonData = [JSONResponse dataUsingEncoding:NSASCIIStringEncoding];
//
// NSLog(#"%#",JSONResponse);
NSError *err;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&err];
NSString *firstName = [NSString stringWithFormat:#"%#", [[json objectAtIndex:i] objectForKey:#"first_name"]];
NSLog(#"%#",firstName); //this prints the actual first name in console But
fname.text=firstName;
NSLog(#"%#",fname.text); //it prints "(Null)" in console
}
}
I think because i was trying to get data from different view and wanted to display the data in another view was the problem.
But by creating the delegate the problem was solves and i can easily send the data from one view to another view.

JSON returning null

I'm having a bit of trouble parsing some returned JSON. I'm fairly new to working with JSON. I'm trying to get the company name from the first JSON array element. I have a feeling that I'm confusing the use of NSMutabeArray and NSMutableDictionary. What I get is null. Any idea what I'm doing wrong?
NSString *url = #"http://www.google.com/finance/info?infotype=infoquoteall&q=C,JPM,AIG,AAPL";
NSData* data = [NSData dataWithContentsOfURL:
[NSURL URLWithString: url]];
//parse out the json data
NSError* error;
NSMutableArray* json = [NSJSONSerialization
JSONObjectWithData:data //1
options:kNilOptions
error:&error];
NSString* companyName = [[json objectAtIndex:0] objectForKey:#"name"] ; //Where I need some help
NSLog(#"we got %#", companyName);
Load that url in your browser. Looks like google is prefixing the JSON with //. I think NSJSONSerialization is tripping on that. Try this
NSRange range = NSMakeRange(2, [data length] - 3);
NSData *noPrefix = [data subdataWithRange:range];
Then send that to the parser.
You put in an error object, but you never looked at it. If you had, you would see that the data is corrupted:
Error Domain = NSCocoaErrorDomain Code = 3840 "The data couldn’t be read because it has been corrupted." (Invalid value around character 1.) UserInfo = 0x10030a8f0 { NSDebugDescription = Invalid value around character 1. }
I changed the value of the options parameter to see this error. I have
NSMutableArray* json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers |NSJSONReadingAllowFragments error:&error];

Removing // from NSMutableArray

When I NSLog the contents of an NSMutableArray I get null. I believe I know what the issue is.
I'm having a bit of trouble trying to figure out how to remove "//" at the beginning of this JSON output. If you load http://www.google.com/finance/info?infotype=infoquoteall&q=AAPL,C into your browser you'll see the "//" at the beginning. I believe that the "//" is what is causing the array to return null. How could I go about removing the two dashes? Below is I have what I've done thus far...
NSString *url = #"http://www.google.com/finance/info?infotype=infoquoteall&q=C,JPM,AIG,AAPL";
NSData* data = [NSData dataWithContentsOfURL:
[NSURL URLWithString: url]];
//parse out the json data
NSError* error;
NSMutableArray* json = [NSJSONSerialization
JSONObjectWithData:data //1
options:kNilOptions
error:&error];
NSLog(#"json is %#", json); //returns "json is (null)"
You can try this:
NSData *newData = [data subdataWithRange:NSMakeRange(4, [data length] -4)];
This gets rid of the first four characters. There was a control character the two slashes and a space before the first "[", and this gets rid of those. I tried this but the data still had a flaw in it further on.