iOS Swift中JSON序列化未终止/无效字符串错误解决求助
我之前也碰到过一模一样的问题!这种NSCocoaErrorDomain Code=3840的错误,本质上就是你从XML里拿到的字符串不符合JSON的语法规范,导致JSON解析器无法正常解析。咱们从几个常见的原因入手,一步步解决:
1. 首要问题:XML字符串包含JSON敏感未转义字符
JSON对字符串格式有严格要求,比如双引号、反斜杠、换行符这些字符必须被转义,否则会直接破坏JSON结构。比如XML里的内容是I love "Swift",直接把这个字符串放进JSON里就会导致引号不匹配,触发"Unterminated string"错误。
解决方案:转义JSON敏感字符
写一个通用的转义函数,在处理XML返回的字符串前先做转义:
func escapeStringForJSON(_ input: String) -> String { var escaped = input // 转义核心敏感字符 escaped = escaped.replacingOccurrences(of: "\"", with: "\\\"") escaped = escaped.replacingOccurrences(of: "\\", with: "\\\\") // 处理换行、回车、制表符 escaped = escaped.replacingOccurrences(of: "\n", with: "\\n") escaped = escaped.replacingOccurrences(of: "\r", with: "\\r") escaped = escaped.replacingOccurrences(of: "\t", with: "\\t") // 移除JSON不允许的控制字符(ASCII 0-31) let controlChars = CharacterSet.controlCharacters escaped = escaped.components(separatedBy: controlChars).joined() return escaped }
2. XML解析时的字符串拼接不完整
foundCharacters方法不是一次性返回元素的全部内容,解析器可能会分多次返回字符片段。如果直接用单次返回的字符去转JSON,就会拿到不完整的字符串,触发"Garbage at end"错误。
解决方案:正确管理解析时的字符串拼接
在XML解析代理方法里,确保只有当元素解析完成时,才处理完整的字符串:
class XMLToJSONParserDelegate: NSObject, XMLParserDelegate { private var currentElementValue: String? func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) { // 开始解析目标元素时,初始化空字符串 if elementName == "你的目标元素名" { currentElementValue = "" } } func parser(_ parser: XMLParser, foundCharacters string: String) { // 追加字符,而不是直接覆盖 currentElementValue?.append(string) } func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) { if elementName == "你的目标元素名", let rawString = currentElementValue { // 先转义,再构造JSON并序列化 let escapedString = escapeStringForJSON(rawString) // 示例:构造包含该值的JSON对象 let jsonString = "{\"result\": \"\(escapedString)\"}" guard let jsonData = jsonString.data(using: .utf8) else { print("字符串转Data失败") return } do { let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: []) print("JSON解析成功:\(jsonObject)") } catch { print("JSON解析错误:\(error.localizedDescription)") } // 重置变量,避免影响下一个元素解析 currentElementValue = nil } } }
3. 额外检查:JSON结构是否合法
有时候错误不是来自字符串内容,而是你构造的JSON本身格式有误。比如少了闭合的引号、逗号,或者嵌套错误。建议在序列化前,先打印你构造的jsonString,手动检查是否符合JSON规范——比如有没有未闭合的引号,有没有多余的逗号等。
4. 特殊情况:CDATA段处理
如果你的XML里包含<![CDATA[...]]>块,虽然foundCharacters会返回CDATA内的内容,但CDATA里往往会包含更多特殊字符,同样需要用上面的转义函数处理,确保所有敏感字符都被转义后再序列化。
按照上面的步骤调整后,应该就能解决那些令人头疼的JSON序列化错误了!
内容的提问来源于stack exchange,提问作者Vignesh Krish

