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

SwiftUI中API调用异常:JSON解码与bedwars_stats获取问题

问题排查与修复方案

核心问题分析

从你的代码和JSON结构来看,主要有以下几个导致解码失败的原因:

  • 结构体命名冲突:Result是Swift标准库中的内置类型,自定义同名结构体会引发编译歧义
  • 字符串插值语法错误:Text组件里的(item.achievements.bedwars_stats)缺少反斜杠,正确写法应为\(item.achievements.bedwars_stats)
  • 解码异常被忽略:使用try?会吞掉解码过程中的错误信息,无法定位具体问题
  • URL变量名重复:URL(string: url)里的url变量名重复,应替换为具体的URL字符串常量
  • 潜在类型不匹配:如果JSON中的bedwars_stats是带引号的字符串类型,而你用Int接收会直接解码失败
  • ForEach标识风险:用bedwars_stats作为唯一id可能出现重复,建议给结构体实现Identifiable协议

修正后的完整代码

import SwiftUI

// 重命名结构体避免和标准库Result冲突
struct PlayerResponse: Codable {
    let results: [PlayerResult]
}

struct PlayerResult: Codable, Identifiable {
    // 实现Identifiable协议生成唯一标识,也可改用JSON中自带的唯一字段
    var id: UUID { UUID() }
    let achievements: PlayerAchievements
}

struct PlayerAchievements: Codable {
    // 若JSON中bedwars_stats是字符串类型,将此处改为String即可
    let bedwars_stats: Int
}

struct ContentView: View {
    @State private var results: [PlayerResult] = []
    
    var body: some View {
        VStack {
            ForEach(results) { item in
                // 修正字符串插值语法
                Text("\(item.achievements.bedwars_stats)")
            }
        }
        .task {
            await loadData()
        }
    }
    
    func loadData() async {
        // 替换为你的实际API地址
        guard let url = URL(string: "你的目标API地址") else {
            print("无效URL")
            return
        }
        do {
            let (data, _) = try await URLSession.shared.data(from: url)
            // 用try代替try?,打印具体错误信息
            let decodedResponse = try JSONDecoder().decode(PlayerResponse.self, from: data)
            results = decodedResponse.results
        } catch {
            // 打印解码错误,快速定位问题
            print("解码失败详情:\(error)")
        }
    }
}

额外调试技巧

  1. 打印原始JSON数据:在解码前添加print(String(data: data, encoding: .utf8)),确认拿到的JSON结构是否和预期一致
  2. 检查字段匹配:JSON的键名必须和结构体属性完全一致(包括下划线、大小写),若JSON用驼峰命名,可设置JSONDecoder的keyDecodingStrategy = .convertFromSnakeCase
  3. 调整结构体层级:如果你的JSON根节点不是results数组,而是直接包含achievements的单个对象,需修改PlayerResponse结构,比如:
struct PlayerResponse: Codable {
    let achievements: PlayerAchievements
}

内容的提问来源于stack exchange,提问作者Tom Miller

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 21:15:33