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

JSON解析失败求助:API返回JSON解析后无法正常获取feeds数据

帮你排查JSON解析的问题

嘿,我看了你贴的代码和遇到的情况,咱们一步步来拆解问题:

首先,先解决代码里的不安全操作

你代码里用了as!和!强制解包,这可是个大坑——如果API返回的JSON结构哪怕有一点不符合预期,直接就会崩溃,而且你用了try?,要是解析失败responseJSON直接是nil,这时候responseJSON!肯定炸。先把这些改成安全的写法:

DispatchQueue.main.async { 
    do {
        // 先安全解析成字典,失败就直接提示
        guard let responseJSON = try JSONSerialization.jsonObject(with: data, options:.allowFragments) as? [String:Any] else {
            print("JSON格式不对,没法转成字典")
            return
        }
        // 再安全取出feeds数组,顺便打印当前JSON内容方便排查
        guard let values = responseJSON["feeds"] as? [[String: Any]] else {
            print("找不到feeds字段,或者它不是数组格式")
            print("当前拿到的JSON: \(responseJSON)")
            return
        }
        print("完整JSON") 
        print(responseJSON) 
        print("Feeds数组") 
        print(values) 
        for value in values { 
            if let temp = value["field1"] as? Float { 
                self.temperatures.append(temp) 
                print("解析到温度: \(temp)")
            } else {
                // 加个else分支,打印出有问题的entry,方便你看哪里错了
                print("这个entry的field1格式不对: \(value["field1"] ?? "没这个字段")")
                print("完整entry内容: \(value)")
            }
        } 
    } catch {
        // 捕获解析错误,直接打印错误信息
        print("JSON解析失败啦,错误原因: \(error.localizedDescription)")
    }
}

然后,你看到的entry...其实是打印截断

别担心,不是JSON没解析完,是Xcode控制台默认会截断过长的打印内容。如果想看到完整的JSON或者feeds数组,可以把对象再转成带格式的字符串打印:

// 打印完整的responseJSON
if let jsonData = try? JSONSerialization.data(withJSONObject: responseJSON, options: .prettyPrinted),
   let jsonString = String(data: jsonData, encoding: .utf8) {
    print("完整JSON内容:\n\(jsonString)")
}

// 打印完整的feeds数组
if let feedsData = try? JSONSerialization.data(withJSONObject: values, options: .prettyPrinted),
   let feedsString = String(data: feedsData, encoding: .utf8) {
    print("完整feeds内容:\n\(feedsString)")
}

还有个可能:类型不匹配

你把field1转成Float,但如果API返回的是Double类型(比如12.5004340278本质是Double),或者是字符串类型(比如"12.5004340278"),直接转Float就会失败。可以试试兼容这几种情况:

for value in values { 
    // 先试转Double,再转Float
    if let tempDouble = value["field1"] as? Double {
        let temp = Float(tempDouble)
        self.temperatures.append(temp)
        print("解析到温度: \(temp)")
    } 
    // 如果是字符串类型,先转字符串再转Float
    else if let tempString = value["field1"] as? String, let temp = Float(tempString) {
        self.temperatures.append(temp)
        print("解析到温度: \(temp)")
    }
    else {
        print("这个entry的field1没法转成Float: \(value["field1"] ?? "无此字段")")
    }
}

最后,确认API返回的原始数据

最稳妥的办法是先看看API返回的原始JSON是什么样的,直接把data转成字符串打印:

if let rawJSONString = String(data: data, encoding: .utf8) {
    print("API返回的原始JSON:\n\(rawJSONString)")
}

这样你就能清楚看到feeds数组的结构,还有field1的实际类型,从根源上解决问题。


内容的提问来源于stack exchange,提问作者Mara M

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:30:34