从jsonbin.io获取JSON数据失败:SwiftUI列表无法填充问题排查
问题原因及解决办法
你的代码问题出在jsonbin.io的返回JSON结构和你预期的不一致,以及错误处理不够严谨导致无法定位问题。
1. Jsonbin.io的返回结构解析错误
Jsonbin.io的公开存储仓返回的JSON并非直接是[Facility]数组,而是包裹在一个包含record字段的顶层对象中,大致结构如下:
{ "record": [ {"id": "xxx", "facilityName": "xxx"}, {"id": "yyy", "facilityName": "yyy"} ], "metadata": { ... } }
你直接尝试解码成[Facility].self,自然匹配失败,导致facilities始终是空数组。
2. 错误处理不严谨
你用了try?来解码,这会让解码失败的错误被静默忽略,你无法看到具体的失败原因,不利于调试。
修改后的代码
struct Facility: Codable, Identifiable { var id: String var facilityName: String } // 新增顶层结构体,匹配jsonbin.io的返回结构 struct JsonBinResponse<T: Codable>: Codable { var record: T } struct FacilityView: View { @State private var facilities = [Facility]() var body: some View { NavigationView { List(facilities, id: \.id) { item in VStack { Text(item.id) .font(.headline) Text(item.facilityName) } } .navigationTitle("Facilities") .task { await fetchData() } } } func fetchData() async { guard let url = URL(string: "https://api.jsonbin.io/v3/b/66130dbead19ca34f85689bc") else { print("URL无效") return } do { let (data, _) = try await URLSession.shared.data(from: url) // 先解码顶层对象,再取出record数组 let decodedResponse = try JSONDecoder().decode(JsonBinResponse<[Facility]>.self, from: data) facilities = decodedResponse.record } catch { // 打印具体错误,方便调试 print("数据解析失败:\(error.localizedDescription)") print("错误详情:\(error)") } } } #Preview { FacilityView() }
关键修改点
- 新增
JsonBinResponse<T>泛型结构体,适配jsonbin.io的返回格式,通过record字段获取实际的数组数据。 - 将
try?替换为try,并在catch块中打印具体错误信息,便于后续调试其他问题。 - 解码时先解析顶层的
JsonBinResponse<[Facility]>,再将record赋值给facilities。
内容的提问来源于stack exchange,提问作者Keith
相关产品推荐
相关产品推荐

