Swift 5 API JSON解码问题求助:结构体构造错误排查
解决JSON解码的结构体匹配问题
嘿Ed,我一眼就看出问题出在哪了——你的结构体层级和JSON的键结构完全不匹配,这才导致了解码失败!
先看看你的JSON结构:
{ "computer": { "location": { "username": "john.smith", "realname": "john smith", "real_name": "johnsmith", "email_address": "johnsmith@company.com", "position": "somePosition", "phone": "123-456-7890", "phone_number": "123-456-7890", "department": "", "building": "", "room": "someRoom01" } } }
它的层级是:外层对象 → "computer"键 → "location"键 → 具体字段
但你写的结构体层级是:ComputerRecord → locationRecord → Location → record → Record,这和JSON的键完全对应不上,解码器自然找不到locationRecord这个键,所以抛出了keyNotFound错误。
修正后的结构体
你需要让结构体的层级和JSON的键一一对应,不需要多余的嵌套:
struct ComputerRecord: Codable { let computer: LocationContainer // 对应JSON里的"computer"键 } struct LocationContainer: Codable { let location: UserInfo // 对应JSON里的"location"键 } struct UserInfo: Codable { let username: String let realname: String let real_name: String let email_address: String let position: String let phone: String let phone_number: String let department: String let building: String let room: String }
或者更简洁的嵌套写法(如果不需要单独拆分容器结构体的话):
struct ComputerRecord: Codable { struct UserInfo: Codable { let username: String let realname: String let real_name: String let email_address: String let position: String let phone: String let phone_number: String let department: String let building: String let room: String } struct LocationContainer: Codable { let location: UserInfo } let computer: LocationContainer }
修正后的解码代码
现在解码时的访问路径也要对应修正后的结构体:
do { let decoder = JSONDecoder() let computerRecord = try decoder.decode(ComputerRecord.self, from: data) if computerRecord.computer.location.username == nameToCheck { usernameSet(true, response, error) } else { print("In the else") usernameSet(false, response, error) } } catch { print("解码错误详情:\(error)") usernameSet(false, response, error) }
额外小提示
如果以后想把JSON里的蛇形命名(比如real_name)改成Swift风格的驼峰命名(realName),可以用CodingKeys做键映射:
struct UserInfo: Codable { let username: String let realname: String let realName: String // Swift风格属性名 let emailAddress: String let position: String let phone: String let phoneNumber: String let department: String let building: String let room: String enum CodingKeys: String, CodingKey { case username, realname, position, phone, department, building, room case realName = "real_name" case emailAddress = "email_address" case phoneNumber = "phone_number" } }
这样修改后,你的解码应该就能正常工作啦!
内容的提问来源于stack exchange,提问作者Edward S.
相关产品推荐
相关产品推荐

