You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift API调用后JSON字符串解码失败及多余逗号处理求助

解决带格式问题的JSON解码失败问题

你拿到的响应不是标准JSON,加上模型类型不匹配,才导致解码失败。按下面步骤修改即可:

1. 先清理非标准的响应字符串

原始返回的字符串有三个问题:外层多双引号、末尾带多余逗号、用了单引号(JSON要求双引号)。拿到数据后先做格式清理:

  • 去掉首尾的双引号
  • 删掉末尾所有多余的逗号
  • 把所有单引号替换成双引号

2. 修正模型的类型匹配问题

JSON里的PM25、lux、VOC等字段都是带小数的数值(比如117.00),你之前定义成Int会解码失败,要统一改成Double;另外用CodingKey映射JSON的大写键名,符合Swift的命名规范。

3. 调整解码逻辑

原始JSON是单个包含result的对象,不是字典数组,所以要解码成IoTData.self,同时把singleData改成单个对象类型(而非数组)。


修正后的模型代码

struct IoTData: Codable {
    let result: ResultData
}

struct ResultData: Codable {
    let ip, id, date, time: String
    let temp: Double
    let pm25, lux, voc: Double
    let co: Double
    let co2, o3: Double
    let rh: Double
    let pres: Double
    
    // 映射JSON中的大写键名
    enum CodingKeys: String, CodingKey {
        case ip, id
        case date = "Date"
        case time = "Time"
        case temp = "Temp"
        case pm25 = "PM25"
        case lux, voc = "VOC"
        case co = "CO"
        case co2 = "CO2"
        case o3 = "O3"
        case rh = "RH"
        case pres = "Pres"
    }
}

修改后的加载解码代码

@Published var singleData: IoTData? // 改为可选的单个对象,而非数组

func loadSingleData() {
    guard let url = URL(string: urlString) else {
        print("无效的URL")
        return
    }
    
    URLSession.shared.dataTask(with: url) { [weak self] data, response, error in
        DispatchQueue.main.async {
            guard let data = data else {
                print("加载数据失败")
                return
            }
            
            // 1. 将Data转为字符串
            guard var rawString = String(data: data, encoding: .utf8) else {
                print("无法将数据转为字符串")
                return
            }
            
            // 2. 清理字符串格式
            rawString = rawString.trimmingCharacters(in: CharacterSet(charactersIn: "\"")) // 去掉首尾双引号
            rawString = rawString.replacingOccurrences(of: ",+$", with: "", options: .regularExpression) // 删掉末尾多余逗号
            rawString = rawString.replacingOccurrences(of: "'", with: "\"") // 单引号转双引号
            
            // 3. 清理后的字符串转回Data
            guard let cleanedData = rawString.data(using: .utf8) else {
                print("无法将清理后的字符串转为Data")
                return
            }
            
            // 4. 解码数据
            let decoder = JSONDecoder()
            do {
                let decodedData = try decoder.decode(IoTData.self, from: cleanedData)
                self?.singleData = decodedData
                print("解码成功:\(decodedData)")
            } catch {
                print("解码失败,错误信息:\(error.localizedDescription)")
                print("详细错误:\(error)") // 打印详细错误方便调试
            }
        }
    }.resume()
}

内容的提问来源于stack exchange,提问作者Karan D

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 21:36:29