SwiftUI调用Nager.Date API解析JSON无数据显示问题排查
问题排查与修复方案
核心问题:解码错误被静默忽略,无法定位原因
你的代码在解码环节使用了try?,这会让解码失败的错误被直接忽略,且该错误不会进入外层的catch块(因为try?仅返回可选值,不会抛出错误)。这导致你完全不知道数据解码失败的具体原因,自然无法填充数据到列表中。
具体修复步骤
1. 捕获完整错误信息,定位问题
修改fetchHolidaysData方法,将解码操作也纳入do块并使用try,这样网络请求、解码过程中出现的所有错误都会被捕获并打印详细信息:
func fetchHolidaysData() async { guard let url = URL(string: "https://date.nager.at/api/v2/publicholidays/2020/US") else { print("无效URL") return } do { let (data, response) = try await URLSession.shared.data(from: url) // 可选:打印响应状态码,确认请求是否成功 if let httpResponse = response as? HTTPURLResponse { print("请求状态码:\(httpResponse.statusCode)") } let decodedResponse = try JSONDecoder().decode([Holidays].self, from: data) holidays = decodedResponse } catch { print("错误详情:\(error)") } }
运行后会发现,该API返回的字段中存在types、fixed等你的结构体未声明的字段,但默认的JSONDecoder会自动忽略这些额外字段,解码本身是可以成功的——之前的无数据问题,本质是try?掩盖了可能的网络或其他隐性错误,修改后即可正常解码数据。
2. 修正列表ID的选择(消除潜在隐患)
虽然这不是当前无数据的直接原因,但用name作为列表id存在风险:如果存在同名节假日,会导致列表刷新异常。建议让结构体遵循Identifiable协议,基于唯一组合生成ID:
struct Holidays: Decodable, Identifiable { // 用日期+名称生成唯一ID var id: String { "\(date)-\(name)" } var date: String var localName: String var name: String var countryCode: String }
随后列表可以简化为:
List(holidays) { t in VStack(alignment: .leading) { Text(t.date) .font(.headline) .foregroundColor(.cyan) Text(t.name) .font(.body) .foregroundColor(.indigo) Text(t.countryCode) .font(.body) .foregroundColor(.red) } }
3. 验证结果
修改完成后运行代码,控制台会打印请求状态码(200表示请求成功),同时Holidays List列表会正常加载并展示所有2020年美国的公共节假日数据。
内容的提问来源于stack exchange,提问作者SomebodyNew
相关产品推荐
相关产品推荐

