Swift解析JSON时获取响应字符串值的问题及解决方案
Swift解析被引号包裹的JSON字符串解决方案
问题场景
调用后端User/UserUndertaking接口时,Postman返回的响应是被双引号包裹的JSON字符串(示例格式:"{\"errorCode\":0,\"status\":\"success\",\"utID\":\"123\",...}")。直接使用JSONDecoder解码UserUndertakingResponse模型,或JSONSerialization解析均失败,报错如下:
翻译后的错误信息
- JSONDecoder错误:
数据损坏(Swift.DecodingError.Context(codingPath: [], debugDescription: "给定的数据不是有效的JSON。", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "对象中没有对应值的字符串键,位于第1行第1列附近。" UserInfo={NSDebugDescription=对象中没有对应值的字符串键,位于第1行第1列附近。, NSJSONSerializationErrorIndex=1})))
- JSONSerialization错误:
Error Domain=NSCocoaErrorDomain Code=3840 "JSON文本未以数组或对象开头,且未设置允许片段的选项。位于第1行第0列附近。" UserInfo={NSDebugDescription=JSON文本未以数组或对象开头,且未设置允许片段的选项。位于第1行第0列附近。, NSJSONSerializationErrorIndex=0}
错误原因
后端返回的不是标准JSON对象/数组,而是一个字符串类型的JSON内容——外层被双引号包裹,本质是单个字符串值,而非JSON结构。解析器期望直接读取JSON结构,因此会抛出格式错误。
解决步骤
- 将原始响应数据转换为字符串;
- 去除字符串首尾的双引号,得到纯净的JSON结构字符串;
- 将处理后的字符串转回
Data类型; - 使用
JSONDecoder正常解码模型,提取目标字段。
修改后的完整解析代码
替换原请求代码中URLSession闭包内的解析逻辑:
URLSession.shared.dataTask(with: request) { data, response, error in guard let data = data, error == nil else { print(error?.localizedDescription ?? "") return } // 解析逻辑修改 do { // 1. 转换为字符串 guard let jsonString = String(data: data, encoding: .utf8) else { print("数据转字符串失败") return } print("原始响应字符串: \(jsonString)") // 2. 去除首尾双引号 let cleanedJsonString = jsonString.trimmingCharacters(in: CharacterSet(charactersIn: "\"")) // 3. 转回Data guard let cleanedData = cleanedJsonString.data(using: .utf8) else { print("处理后字符串转Data失败") return } // 4. 解码模型 let decoder = JSONDecoder() let responseModel = try decoder.decode(UserUndertakingResponse.self, from: cleanedData) // 提取目标字段 print("utID: \(responseModel.utID)") print("showUserUndertaking: \(responseModel.showUserUndertaking)") print("htmlDescription: \(responseModel.htmlDescription)") } catch { print("解析错误: \(error)") } }.resume()
额外说明
如果后端返回的字符串包含转义的双引号(例如htmlDescription字段内的转义内容),处理后的字符串转回Data时会自动处理转义,JSONDecoder能正确解析内部字段,无需额外操作。
内容的提问来源于stack exchange,提问作者Swift
相关产品推荐
相关产品推荐

