Parsing JSON Issues

Discussion in 'iOS Programming' started by harryslotwiner, Mar 28, 2012.

  1. harryslotwiner macrumors newbie

    Mar 28, 2012
    So right now I am having issues parsing JSON for an application that I am working on. I am using the Stig Brautaset JSON classes to attempt to parse JSON from google reader here's an example:
      "author": "Harry",
      "continuation": "...",
      "direction": "ltr",
      "id": "user/userid/state/",
      "items": [
          "alternate": [
              "href": "",
              "type": "text/html"
          "annotations": [
          "author": "",
          "categories": [
          "comments": [
          "crawlTimeMsec": "1332983007944",
          "id": ",2005:reader/item/90cd9acd9c62942f",
          "likingUsers": [
          "origin": {
            "htmlUrl": "",
            "streamId": "feed/",
            "title": "Test XML"
          "published": 1332982620,
          "summary": {
            "content": " Amazing Content",
            "direction": "ltr"
          "timestampUsec": "1332983007944330",
          "title": "An Amazing Article",
          "updated": 1332982620
      "title": "Harry's reading list in Google Reader",
      "updated": 1332983007
    This is the code that I am using to parse it:
    #import "JSONTestViewController.h"
    #import "JSON.h"
    @implementation JSONTestViewController
    @synthesize responseData;
    #pragma mark -
    #pragma mark Fetch loans from internet
    	self.responseData = [NSMutableData data];
        NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@""]];
        [[NSURLConnection alloc] initWithRequest:request delegate:self];
    - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
        [responseData setLength:0];
    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
        [responseData appendData:data];
    - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    	[connection release];
    	self.responseData = nil;
    #pragma mark -
    #pragma mark Process loan data
    - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
        [connection release];
        NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
    	self.responseData = nil;
    	NSArray* items = [(NSDictionary*)[responseString JSONValue] objectForKey:@"items"];
    	[responseString release];
    	//choose a random loan
    	NSDictionary* item = [items objectAtIndex:1];
    	NSString* name = [item objectForKey:@"title"];
    	//set the text to the label
    	label.text = name; //[NSString stringWithFormat:@"%@ - %@", name,author];
    Which is not working, it returns this error:
    I'm new to JSON and can't seem to figure out why this isn't working, what am I doing wrong?

    Thanks for any help.
  2. chown33 macrumors 604

    Aug 9, 2009
    Does your JSON text validate?
    Google search terms: json validator
  3. harryslotwiner thread starter macrumors newbie

    Mar 28, 2012
  4. chown33 macrumors 604

    Aug 9, 2009
    Then you need to test the parsing code with test data.

    Start with a file of data containing exactly one JSON item. Make sure it's the same as the item your code looks for ("title", right?). Run your program reading the test data from the file. Does it work?

    Next, construct test data in a file that contains about half the JSON you posted. Try parsing that. If it works, try the other half. If both work, put 3/4 of the whole text in the test file, try again. Repeat until you identify the part that fails. Then start pruning it until you identify exactly what's causing the parser to fail.

    If all the test data in a file works, then maybe what's in the file isn't identical to what you're receiving from the URL. Write that NSData received to a file, exactly as received. Test with that.

    If you find the character or text, look at it with a hex-dump tool like HexFiend (google it).

    Alternative strategy: Search the parser source code (it's available, right?) for the message you posted. Put an NSAssert there that identifies the actual character (or whatever) that caused the error. An NSAssert will cause an exception, which will produce a stack trace with more detailed info than just an error message.

    Simplified strategy: Google this text from the error message: brautaset.JSON.ErrorDomain

    Found this:
  5. harryslotwiner thread starter macrumors newbie

    Mar 28, 2012
    Ok, Sorry I haven't been on a while I was pretty busy this week.

    I found out the problem but not the solution, the problem is that the URL where I am trying to get the JSON from does contain JSON however it is not recognized as a JSON file. I guess it just appears as a text file.

    So, how can I convince my app that it is JSON?

    I thought about loading the URL in a web view, pulling the text from a web view and then putting that in a JSON file and parsing that. Is that possible? The getting the content from the browser is easy, can you write to .json files locally? Then how would you parse a local file?

    By the way, the URL for the JSON for Google Reader is here. You have to be signed into a Google Account with at least 1 unread article.
  6. chown33 macrumors 604

    Aug 9, 2009
    That doesn't make sense. JSON is text. Plain old pure text.

    If you're feeding the HTML data-stream to a JSON parser, then there's nothing that needs to "recognize a JSON file". If the content is JSON, it's parsed successfully. If it's not JSON, it won't be parsed successfully. The outcome is entirely up to the parser. You could feed your JSON parser the URL of a GIF file, and it would still be parsed as JSON. It would fail badly, but that's because GIF isn't JSON text.

    If you're saying that the data-stream isn't pure JSON, that's a different issue. Then you need to look at the complete actual data-stream and find the faulty characters. Looking at it after the JSON parser fails won't help. You need the actual data.

    I suggest putting a known-good JSON text file at a known URL, say something on S3, and then telling your program to load that. You could also turn on Personal Web Sharing on your Mac (System Preferences > Sharing pane), put a known-good JSON file in your Sites folder, and get that URL.

    Or download the exact URL that's causing the failure, e.g. using the 'curl' command-line or a tool like CyberDuck, and look at it in a hex-dump program like HexFiend (google it). Or befriend the 'tcpdump' command.

Share This Page