NSJSONSerialization - "字符串解析过程中意外的文件结尾"

Chr*_*ler 2 json ios nsjsonserialization

我有一些问题有线解析一些REST的反应时.问题是,我不能复制.有时它会发生,我在错误日志中没有相应的信息.

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).}
Run Code Online (Sandbox Code Playgroud)


对不起,由于敏感的用户数据,我不允许从JSON-Response中提供任何信息(它只出现在一些内部帐户中,其中错误日志级别设置为低以检测此问题).


其他一些信息:

  • JSON有效(通过http://jsonlint.com/查看)
  • 当试图重现这个问题,我让其他NSError说明,如:
    • 位置XYZ处的字符无效
    • 无效的对象
    • ...



UPDATE 1:解析机构(NSData的的扩展)

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

    return jsonObject;
}
Run Code Online (Sandbox Code Playgroud)



更新2:用于下载数据的NSOperation - 主要()的内容 - >更新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
}
Run Code Online (Sandbox Code Playgroud)



更新3: JSON-Object结构

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



我很高兴有任何信息或提示如何强制此错误代码.

最诚挚的问候,
克里斯

old*_*man 5

问题再现

导致此问题的原因是stringin json包含非法的Unicode Point.以下代码可以重现此问题.

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

根据JSONKit中的Readme.md,您可以将其JSONKit用作额外的解析器.例如

 id result = [NSJSONSerialization JSONObjectWithData:data options:options error:&error];
 if (error) {          
     error = nil;
     result = [data objectFromJSONDataWithParseOptions:JKParseOptionLooseUnicode error:& error];   // use JSONKit
 }
Run Code Online (Sandbox Code Playgroud)