今日在程序中發現一個解析json報錯的問題,總是報如下錯:
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=0x7fc9b3646520 {NSDebugDescription=Unexpected end of
file during string parse (expected low-surrogate code point but did not
find one).
搜了下low-surrogate code point發現是缺少低位代理碼,導致無法正常解析json數據。
仔細檢查了下數據來源發現當用戶發布的文字內容是“給自己一個微笑也給他人一個微笑????”時,后臺在截取一定長度字符串的時候剛好截取到表情符號的編碼位置,導致截取了一部分表情編碼給我:
"newContent": {
"id": "56",
"title": null,
"articleThumbImage": null,
"articleType": null,
"content": "給自己一個微笑也給他人一個微笑?",
"weburl": null,
"action": null,
"linkEntityId": null,
"userId": null,
"userName": null,
"userGender": null,
"userIcon": null,
"userTitle": null,
"praiseCount": null,
"commentCount": null,
"circleName": null,
"circleThumbImage": null
},
由此看見content字段中包含了第一個表情的一部分編碼,因為缺少后面一部分編碼,所以導致iOS這邊無法正常解析該json。
這個是我們在截取字符串長度的時候容易忽略考慮到的地方。谷歌搜了下Error Domain=NSCocoaErrorDomain Code=3840關鍵字,發現之前有人也遇到過類似的問題,但是都不是這個問題,特做此記錄,希望能幫到大家。
2016-2-17補充:
由于后臺人員不給解決這個問題要客戶端自己處理,經過查閱發現JSONKit可以處理這個問題,我暫時就使用了JSONKit來處理這種問題:
id result = [NSJSONSerialization JSONObjectWithData:data options:options error:&error];
if (error) { error = nil; result = [data objectFromJSONDataWithParseOptions:JKParseOptionLooseUnicode error:& error];
// use JSONKit }
原文:
NSJSONSerialization - “Unexpected end of file during string parse”
2018-12-01補充
出現這個問題往往是由于字符串被“非正常截斷”導致的,比如文中講到的,當字符串中包含了表情或者特殊字符,當它們的編碼長度是兩位或者三位時,如果在我們截斷字符串的時候剛好把一部分編碼給截斷了,就會導致沒法正常的解碼了。所以,我們在截取字符串的時候要謹慎一點,建議使用以下方法來截取:
NSRange realRange = [text rangeOfComposedCharacterSequencesForRange:NSMakeRange(0, maxNum)];
text = [text substringWithRange:realRange];