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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 14:56:20