Question

i have some wired issue when Parsing some REST-Response. The problem is, that i can't reproduce it . Sometimes it happens, and I have no corresponding information in the error logs.

Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (Unexpected end of file during string parse (expected low-surrogate code point
but did not find one).) UserInfo=0x157bddb0 {NSDebugDescription=Unexpected end of file during string parse (expected low-surrogate code point but did not find one).}


I'm sorry, I'm not allowed to give you any information from the JSON-Response because of sensitive user data (It only appears on some in-house accounts, where the error log level is set low to detect this issue).


Some other information:

  • The JSON is valid (Checked via http://jsonlint.com/)
  • When trying to reproduce this issue i get other NSError Descriptions, like:
    • Character at position XYZ is invalid
    • Invalid Object
    • ...



UPDATE 1: Parse mechanism (Extension of NSData)

- (NSDictionary *)objectFromJSONDataWithError:(NSError **)error {
    NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData: self
                                                               options: 0
                                                                 error: error];

    return jsonObject;
}



Update 2: NSOperation for downloading data - Content of main() --> Calls function in Update 1

NSURLResponse *response = nil;
NSError *error = nil;
NSData *data = nil;

for (NSInteger i=0; i<kMaxRequestRetry; i++) {
    data = [NSURLConnection sendSynchronousRequest: request
                                 returningResponse: &response
                                             error: &error];

    if (!error) {
        // Handling internal errors and retry mechanism
    }

    [NSThread sleepForTimeInterval:1.0];
}

// Check http status code
NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];
if (statusCode < 200 || statusCode >= 300) {
    CLogWarn(@"Request finished with status code = %d", (int)statusCode);
}

// Evaluate response
if (error) {
    CLogError(@"%@", error);
    [self requestFinishedWithResult:@"{\"errorCode\":99}";
    return;
} else {
    NSError *parseError = nil;
    NSDictionary *responseDic = [data objectFromJSONDataWithError:&parseError];

    // Detect parse issues
    if (parseError) {
        CLogError(@"JSONParse-Error: %@", parseError);
        [self requestFinishedWithResult:[NSString stringWithFormat:@"{\"errorCode\":%d}", (11000 + (int)parseError.code)]];
        return;
    }

    // Success handling
}



Update 3: JSON-Object structure

{
  "errorCode": 0,
  "conversations": [
      {
          "address": "+43664000000",
          "snippet": "This is an dummy text",
          "messagesUnread": 1,
          "messagesUnsent": 2,
          "messages": 9,
          "maxMessageId": 151672,
          "dateLastMessage": 1386353756858
      }
  ]
}



I'm happy for any information or tips how to force this error code.

Best Regards,
Chris

Was it helpful?

Solution 2

Found the issue. The "snippet" in the json object contains a substring from the original message. Our API (written in java) use the substring method and this cuts of the surrogate-pair. The android and windows clients have no problem with this and only show an invalid char, but the NSJSONSerialization throws this error.

Got an tip via the apple dev forum: https://devforums.apple.com/message/961738#961738

OTHER TIPS

Issue Reproduction

Cause of this issue is that the string in json contains illegal Unicode Point. The following code can reproduce this issue.

NSString* test = @"{\"\\ud801\" : 1}";
NSError* error = nil;
id result = [NSJSONSerialization JSONObjectWithData:[test dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&error];
NSLog(@"error: %@", error);

Solution

According to Readme.md in JSONKit, you can use JSONKit as an additional parser. e.g.

 id result = [NSJSONSerialization JSONObjectWithData:data options:options error:&error];
 if (error) {          
     error = nil;
     result = [data objectFromJSONDataWithParseOptions:JKParseOptionLooseUnicode error:& error];   // use JSONKit
 }
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top