0

I use the following method to parse json data returned from my server:

NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"LINK HERE.php"]];

NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];

NSLog(@"%@", error);
if (json) {
    NSArray *quotables = json[@"quotables"];
    for (NSDictionary *quotableDict in quotables) {
        HonorableMention *quotable = [NSEntityDescription insertNewObjectForEntityForName:@"HonorableMention" inManagedObjectContext:self.user.managedObjectContext];
        quotable.body = quotableDict[@"quote"];
        quotable.numLikes = quotableDict[@"num_likes"];
        quotable.user = tmpUser;
    }
    NSArray *didYouKnows = json[@"did_you_knows"];
    for (NSDictionary *didYouKnowDict in didYouKnows) {
        HonorableMention *didYouKnow = [NSEntityDescription insertNewObjectForEntityForName:@"HonorableMention" inManagedObjectContext:self.user.managedObjectContext];
        didYouKnow.body = didYouKnowDict[@"question"];
        didYouKnow.numLikes = didYouKnowDict[@"num_likes"];
        didYouKnow.user = tmpUser;
    }
}

The data is formatted as follows and passes validation at jsonlint.com:

{
    "quotables":[
        {
            "quote":"\"This is fo real\" by Carlo Abelli, Class III",
            "num_likes":"0"
        },
        {
            "quote":"\"We put a lot of effort into this, so this is not going to fail\" by Alex Yu, Class III",
            "num_likes":"0"
        }
    ],
    "did_you_knows":[
        {
            "question":"Did you know that you guys better like this idea?",
            "num_likes":"0"
        },
        {
            "question":"Did you know that you should listen to the first post?",
            "num_likes":"0"
        }
    ]
}

The json serialization fails with the error:

Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (No string key for value in object around character 1.) UserInfo=0x1093e0050 {NSDebugDescription=No string key for value in object around character 1.}

An NSLog of the data returned from the server:

<7b71756f 7461626c 65733a5b 7b227175 6f746522 3a225c22 54686973 20697320 666f2072 65616c5c 22206279 20436172 6c6f2041 62656c6c 692c2043 6c617373 20494949 222c226e 756d5f6c 696b6573 223a2230 227d2c7b 2271756f 7465223a 225c2257 65207075 74206120 6c6f7420 6f662065 66666f72 7420696e 746f2074 6869732c 20736f20 74686973 20697320 6e6f7420 676f696e 6720746f 20666169 6c5c2220 62792041 6c657820 59752c20 436c6173 73204949 49222c22 6e756d5f 6c696b65 73223a22 30227d5d 2c646964 5f796f75 5f6b6e6f 77733a5b 7b227175 65737469 6f6e223a 22446964 20796f75 206b6e6f 77207468 61742079 6f752067 75797320 62657474 6572206c 696b6520 74686973 20696465 613f222c 226e756d 5f6c696b 6573223a 2230227d 2c7b2271 75657374 696f6e22 3a224469 6420796f 75206b6e 6f772074 68617420 796f7520 73686f75 6c64206c 69737465 6e20746f 20746865 20666972 73742070 6f73743f 222c226e 756d5f6c 696b6573 223a2230 227d5d7d>
carloabelli
  • 4,289
  • 3
  • 43
  • 70
  • try this: json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error] – Magyar Miklós Mar 24 '14 at 21:21
  • @incmiko Thanks for the suggestion, but same error. – carloabelli Mar 24 '14 at 21:23
  • my test working fine, how are you getting the data source? – Shams Ahmed Mar 24 '14 at 21:26
  • @ShamsAhmed Added line to question. – carloabelli Mar 24 '14 at 21:29
  • 1
    use dataWithContentsOfURL:options:error: instead to see if there been a error in receiving data – Shams Ahmed Mar 24 '14 at 21:32
  • Convert `data` to NSString and dump it. I'm guessing it gets garbled in transmission somehow. – Hot Licks Mar 24 '14 at 21:38
  • @HotLicks I checked that first thing. The string comes out perfectly using `UTF8` encoding. – carloabelli Mar 24 '14 at 22:05
  • 2
    If your NSData starts with a Byte Order Mark, you wouldn't see that in the UTF-8 string. Would be _really_ helpful to see the actual bytes. After all, the parser complains about something near byte 1. – gnasher729 Mar 24 '14 at 23:24
  • @gnasher729 - Though NSJSONSerialization should handle a byte order mark without any difficulty. – Hot Licks Mar 25 '14 at 00:44
  • Probably you need to NSLog the NSData object directly and pick through the first 20 or so characters by hand. – Hot Licks Mar 25 '14 at 00:45
  • Turns out that there was a strange quotation problem. For some reason the quotes were appearing when we viewed the String around `quotables` and `did_you_knows`, but JSONSerialize was not recognizing them. I have no idea why this was occurring, but adding another pair of explicit quotation marks appears to have resolved the issue. – carloabelli Mar 25 '14 at 02:54

1 Answers1

1

With all the code snippet and Json data your provided everything seems to working fine. Check the example which has similar json data direct from a server:

    NSError *error;
    NSURL *url = [NSURL URLWithString:@"https://dl.dropboxusercontent.com/s/ri4vqz7huascopc/json?dl=1&token_hash=AAEaTEDSF-_t_t1Gmp9_WYNsnbShulGSKmIk89FkAUOTsw"];

    NSData *data = [NSData dataWithContentsOfURL:url
                                         options:NSDataReadingMappedAlways
                                           error:&error];


    NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data
                                                               options:NSJSONReadingMutableContainers
                                                                 error:&error];

    if (!error) {
        NSLog(@"result: %@", dictionary[@"quotables"]);
    } else {
        NSLog(@"json error: %@", error.localizedDescription);
    }

If that implementation doesn't work your PHP may be sending a json with BOM. Check this question for more details. BOM doc here

Community
  • 1
  • 1
Shams Ahmed
  • 4,498
  • 4
  • 21
  • 27
  • While researching BOMs the problem seems to have resolved itself (I have no idea how). Unfortunately now I cannot verify that there was a BOM at the beginning causing the error (it does sound likely). If the problem comes back what is the best way of getting rid of BOMs in php? – carloabelli Mar 24 '14 at 23:55
  • Only way is to modify your PHP script to better checks or be more lenient. Check the comments from the [PHP docs](http://www.php.net/manual/en/function.json-decode.php), there a few methods to could add. – Shams Ahmed Mar 25 '14 at 00:14
  • I was talking about encoding the json but I will take a look in the docs. Thanks. – carloabelli Mar 25 '14 at 00:16
  • can't comment on encoding much as I don't know where the data coming from and the how it's been implemented... Most cases your first double check if the data is already on UTF8 before encoding.. – Shams Ahmed Mar 25 '14 at 00:23
  • Its coming from a mysql database. The encoding is set to UTF8. – carloabelli Mar 25 '14 at 00:58
  • The problem has returned. I `NSLog` the data I get and I added it to the question. – carloabelli Mar 25 '14 at 02:31