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
相关产品推荐
相关产品推荐

