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

Swift数据模型无法解析JSON响应,请求技术支持

问题修正方案

你的代码存在几个关键错误导致无法正确解析JSON,以下是修正后的完整代码和关键点说明:

1. 修正数据模型

import Foundation

struct RatingsResources: Codable {
    // 与JSON顶层键"resources"完全匹配
    let resources: [GolfCourseRating]?
}

struct GolfCourseRating: Codable {
    let id: UUID
    let courseID: Int?
    let teeColor: String?
    let teeboxtype: String?
    // JSON中slope是整数类型,修正为Int?
    let teeslope: Int?
    let teerating: Double?
    
    // Codable协议默认识别名为CodingKeys的枚举,修正命名错误
    enum CodingKeys: String, CodingKey {
        case courseID = "courseid"
        case teeColor = "color"
        case teeboxtype
        case teeslope = "slope"
        case teerating = "rating"
    }
    
    // 自定义解码初始化,给id生成默认UUID(JSON中无此字段)
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        courseID = try container.decodeIfPresent(Int.self, forKey: .courseID)
        teeColor = try container.decodeIfPresent(String.self, forKey: .teeColor)
        teeboxtype = try container.decodeIfPresent(String.self, forKey: .teeboxtype)
        teeslope = try container.decodeIfPresent(Int.self, forKey: .teeslope)
        teerating = try container.decodeIfPresent(Double.self, forKey: .teerating)
        id = UUID()
    }
}

2. 修正网络请求与解码逻辑

func getCourseRating(courseID: String?) {
    let semaphore = DispatchSemaphore(value: 0)
    
    print("GETTING COURSE TEE RATINGS..........")
    
    let urlString: String = "https://api.golfbert.com/v1/courses/\(courseID ?? "4800")/teeboxes"
    
    print("API STRING: \(urlString) ")
    
    // 简化URL创建,增加有效性校验
    guard let url = URL(string: urlString) else {
        print("无效的URL")
        semaphore.signal()
        return
    }
    
    let request = URLRequest(url: url).signed
    let task = URLSession.shared.dataTask(with: request) { data, response, error in
        // 确保无论分支如何都会释放信号量,避免死锁
        defer { semaphore.signal() }
        
        guard let data = data else {
            print("数据获取失败: \(error?.localizedDescription ?? "未知错误")")
            return
        }
        
        print("*******Data String***********")
        print(String(data: data, encoding: .utf8)!)
        print("***************************")
        
        // 用do-catch替代强制解包,捕获解码错误
        do {
            let ratingsData = try JSONDecoder().decode(RatingsResources.self, from: data)
            print("资源数量: \(ratingsData.resources?.count ?? 0)")
            
            // 回到主线程更新UI数据
            DispatchQueue.main.async {
                self.ratingresources = ratingsData
            }
        } catch {
            print("解码错误: \(error)")
        }
    }
    
    task.resume()
    semaphore.wait()
}

关键错误点说明

  • 字段名不匹配:原模型中golfcourserating与JSON顶层键resources不符,修正后直接对应
  • CodingKeys命名错误:Codable协议只识别名为CodingKeys的枚举,原代码的CodingKeysRatings无法被识别
  • 类型不匹配:JSON中slope是整数类型,原模型定义为Double?会导致解码失败
  • UUID字段处理:原代码中id: UUID = UUID()会让Codable尝试解码该字段,JSON中无此键会报错,通过自定义初始化解决
  • 错误的解码目标:原代码尝试解码[RatingsResources].self(数组),但实际返回的是单个JSON对象
  • 强制解包风险:try!会导致解码失败时崩溃,改用do-catch捕获并打印错误

内容的提问来源于stack exchange,提问作者brandon aho

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 01:45:34