9

I use the NSJSONSerialization's JSONObjectWithData:data options: error: to parse JSON data returned from a server.

Now for the options parameter I use: NSJSONReadingAllowFragments. You can look below and see the actual JSON (where I believe the problem is).

The error message I get is:

Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (Invalid value around character 0.) UserInfo=0x6895da0 {NSDebugDescription=Invalid value around character 0.}

Any idea how to fix it?

JSON =

{"name":"Johan Appleseed",
"email":"j.appleseed@emuze.co",
"phone":"+4121876003",
"accounts":{
    "facebook":[true,1125],
    "twitter":[false,null],
    "homepage":[true,"http:\/\/johnAplleseed.com\/index.html"]}}
Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
byteSlayer
  • 1,806
  • 5
  • 18
  • 36
  • Maybe it's because the JSON is returned as a String not as Data? The JSON in itself is valid. Maybe have a look here: http://stackoverflow.com/questions/8356842/how-to-use-nsjsonserialization – Torsten Walter Aug 22 '12 at 10:56

6 Answers6

12

Probably you have some unprintable character that you cannot see. Try this:

NSData *jsonData = ...
const unsigned char *ptr = [data bytes];

for(int i=0; i<[data length]; ++i) {
  unsigned char c = *ptr++;
  NSLog(@"char=%c hex=%x", c, c);
}

To verify you don't have unprintable characters at the beginning or end of the data.

EDIT: to clarify, just run the above on your JSON dictionary - the one that fails to parse.

David H
  • 40,852
  • 12
  • 92
  • 138
  • well i run that and in the log i got all the characters of an html page (opening and closing html, head, and body tags), with the whole JSON response in the body section (seems legit)... Now is that OK? Is there anything special i should be looking for? – byteSlayer Aug 22 '12 at 19:39
  • What you should be looking for in my code are non-ascii characters (strictly non UTF-8 ones). Many people have had your problem because of leading 0s or other small hex values. You showed us an example above - if you have a similar small set of code from a real page, post it. The only thing I'm not use to seeing is a '\' character but I cannot image thats a problem buried in a string. – David H Aug 22 '12 at 21:57
  • well to generate the JSON i simply create an array (all in PHP) and use the PHP JSON ENCODE method to turn it into a JSON response.... you can view the actual code on http://www.socialnow.emuze.co/getUserDetails.php – byteSlayer Aug 23 '12 at 06:57
  • This really helps a lot of time. Now I can simply see the characters and message if any which is the reason of this specific error. – Harjot Singh May 17 '15 at 12:15
2

Ive acctualy discovered the problem to be the fact that the return from the URL is an HTML page, ant there all these html, head, and body tags around the actual response, so it can't be parsed. This is a good Q&A on how to remove the HTML tags from the response (after it has been changed into a string) : Remove HTML Tags from an NSString on the iPhone

Community
  • 1
  • 1
byteSlayer
  • 1,806
  • 5
  • 18
  • 36
1

I had the same problem for a while, I just figured out that if I'm pulling data from a webpage let's say PHP page, there should not be any HTML tags in that page. So a structure like:

<html>
<body>
<?php

?>
</body>
</html>

will ruin your result. turning it into:

<?php

?> 

worked for me.

Behrad3d
  • 439
  • 1
  • 4
  • 13
0

It's been a while but an easier way of printing the data is:

NSLog(@"%@", [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);

Yariv Nissim
  • 13,273
  • 1
  • 38
  • 44
0

One way is there , you can parse jsondata by post request

 -(void)callWebserviceList
 {
spinner.hidden=NO;

NSString *bodyData = @"code_request=monuments_list&asi_id=1";

NSMutableURLRequest *postRequest = [NSMutableURLRequest requestWithURL:[NSURL   URLWithString:@"http://asicircles.com/server_sync.php"]];

// Set the request's content type to application/x-www-form-urlencoded
[postRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];

// Designate the request a POST request and specify its body data
[postRequest setHTTPMethod:@"POST"];
[postRequest setHTTPBody:[NSData dataWithBytes:[bodyData UTF8String] length:strlen([bodyData UTF8String])]];

connection1 = [NSURLConnection connectionWithRequest:postRequest delegate:self];

if(connection1 !=nil)
{
    ////NSLog(@"%@",postRequest);
}

}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {

if ([connection isEqual:connection1 ])
{
     [responseData setLength:0];

}else if ([connection isEqual:connection2 ])
{
     [responseData1 setLength:0];
}

} - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {

    if ([connection isEqual:connection1 ])
  {
    [responseData appendData:data];

}else if ([connection isEqual:connection2 ])
{
     [responseData1 appendData:data];
}


//**check here for responseData & also data**

}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
NSLog(@"%@",[NSString stringWithFormat:@"Connection failed: %@", [error description]]);
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
if ([connection isEqual:connection1 ])
{
    spinner.hidden=YES;
    NSError *error;

    NSDictionary* json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];

    NSMutableArray *arrdata=[json objectForKey:@"message"];
    NSLog(@"code is%@", json);

    for (int i=0; i< arrdata.count; i++)
    {
        [arrDetails addObject:[[arrdata objectAtIndex:i]objectForKey:@"details"]];
        [arrImageUrl addObject:[[arrdata objectAtIndex:i]objectForKey:@"image"]];
        [arrLat addObject:[[arrdata objectAtIndex:i]objectForKey:@"lat"]];
        [arrLongi addObject:[[arrdata objectAtIndex:i]objectForKey:@"longi"]];
        [arrName addObject:[[arrdata objectAtIndex:i]objectForKey:@"name"]];
        [arrLoc addObject:[[arrdata objectAtIndex:i]objectForKey:@"location"]];
        [arrID addObject:[[arrdata objectAtIndex:i]objectForKey:@"id"]];

        NSLog(@"code is%@",[[arrdata objectAtIndex:i]objectForKey:@"details"]);
        NSLog(@"code is%@",[arrImageUrl objectAtIndex:i]);

    }



    if (arrName.count > 0)
    {
        [self addscrollView];
    }



}else if ([connection isEqual:connection2 ])
{

}


}
Dinesh Patel
  • 142
  • 1
  • 7
0

You can also hit url for json data by block in ios

 #define kBgQueue dispatch_get_global_queue(
 DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) //1
#define kLatestKivaLoansURL [NSURL URLWithString: 
 @"http://api.kivaws.org/v1/loans/search.json?status=fundraising"] //2

The first thing we need to do is download the JSON data from the web. Luckily, with GCD we can do this in one line of code! Add the following to ViewController.m:

- (void)viewDidLoad
{
[super viewDidLoad];

dispatch_async(kBgQueue, ^{
    NSData* data = [NSData dataWithContentsOfURL: 
      kLatestKivaLoansURL];
    [self performSelectorOnMainThread:@selector(fetchedData:) 
      withObject:data waitUntilDone:YES];
});
}
- (void)fetchedData:(NSData *)responseData {
//parse out the json data
NSError* error;
NSDictionary* json = [NSJSONSerialization 
    JSONObjectWithData:responseData //1

    options:kNilOptions 
    error:&error];

NSArray* latestLoans = [json objectForKey:@"loans"]; //2

NSLog(@"loans: %@", latestLoans); //3
}
Dinesh Patel
  • 142
  • 1
  • 7