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
相关产品推荐
相关产品推荐

