在解析一些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).}
对不起,由于敏感的用户数据,我不允许从JSON-Response中提供任何信息(它只出现在一些内部帐户中,其中错误日志级别设置为低以检测这个问题)。
其他一些信息:
更新1:解析机制(NSData扩展)
- (NSDictionary *)objectFromJSONDataWithError:(NSError **)error {
NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData: self
options: 0
error: error];
return jsonObject;
}
更新2:用于下载数据的NSOperation - main()的内容 - >更新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
}
更新3: JSON-Object结构
{
"errorCode": 0,
"conversations": [
{
"address": "+43664000000",
"snippet": "This is an dummy text",
"messagesUnread": 1,
"messagesUnsent": 2,
"messages": 9,
"maxMessageId": 151672,
"dateLastMessage": 1386353756858
}
]
}
我很高兴有任何信息或提示如何强制使用此错误代码。
最诚挚的问候,
克里斯
答案 0 :(得分:5)
问题再现
此问题的原因是string
中的json
包含非法的Unicode Point。以下代码可以重现此问题。
NSString* test = @"{\"\\ud801\" : 1}";
NSError* error = nil;
id result = [NSJSONSerialization JSONObjectWithData:[test dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&error];
NSLog(@"error: %@", error);
<强>解决方案强>
根据Readme.md in JSONKit,您可以使用JSONKit
作为额外的解析器。 e.g。
id result = [NSJSONSerialization JSONObjectWithData:data options:options error:&error];
if (error) {
error = nil;
result = [data objectFromJSONDataWithParseOptions:JKParseOptionLooseUnicode error:& error]; // use JSONKit
}
答案 1 :(得分:1)
发现了这个问题。 json对象中的“片段”包含原始消息的子字符串。我们的API(用java编写)使用substring方法和代理对的这种切割。 android和Windows客户端对此没有任何问题,只显示一个无效的char,但是NSJSONSerialization会抛出此错误。
通过apple dev论坛获得提示:https://devforums.apple.com/message/961738#961738