2014-04-15 43 views
2

解析某些REST響應時,我遇到了一些有線問題。問題是,我無法重現它。有時會發生,並且我在錯誤日誌中沒有相應的信息。

NSJSONSerialization - 「字符串解析期間文件意外結束」

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-響應的任何信息(只出現在一些內部賬戶,其中,錯誤日誌級別設置爲低以檢測此問題)。


其他一些信息:

  • 的JSON是有效的(通過http://jsonlint.com/經過)
  • 當試圖重現這個問題,我讓其他NSError描述,如:
    • 在位置XYZ字無效
    • 無效對象
    • ...



UPDATE 1:解析機構(NSData的的擴展)

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

    return jsonObject; 
} 



更新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 
} 



更新3: JSON-對象結構

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



我很高興的任何信息或提示如何強制此錯誤代碼。

最好的問候,
克里斯

+1

錯誤消息表明您嘗試解析* incomplete * JSON對象。沒有更多的信息(例如,*解析如何完成),可能很難提供幫助。 –

+0

如何顯示失敗的JSON本身可能會剝離敏感數據? –

+0

@ Lukasz'Severiaan'Grela:請參閱更新1 - 適用於所有其他15個請求。我認爲在一些json值中必須存在一些損壞的字符。 –

回答

1

發現的問題。 json對象中的「片段」包含原始消息的子字符串。我們的API(用java編寫)使用子字符串方法和這個替代對的削減。 Android和Windows客戶端沒有問題,只顯示無效的字符,但NSJSONSerialization引發此錯誤。

得到通過蘋果開發論壇的提示:https://devforums.apple.com/message/961738#961738

5

問題再現

導致此問題的是,在jsonstring包含非法的Unicode點。以下代碼可以重現此問題。

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作爲附加解析器。例如

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