Swift自定义解码:合并属性构建Dog与Cat结构体
Swift中MyPets结构体JSON解码问题的解决方案
问题背景
需要将给定的JSON数据解码到MyPets结构体中,核心需求是将顶层的catName/dogName字段,与嵌套在cat/dog对象中的属性合并,分别构建完整的Cat和Dog实例。原尝试因未正确实现解码逻辑,且未处理JSON中weight字段的字符串转Int问题,导致解码失败。
原结构体代码:
struct MyPets: Decodable { let dog: Dog let cat: Cat // enum CodingKeys: String, CodingKey { // case dog // case cat // case catName // case dogName // } public init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) // values only has dog and cat } } struct Dog { let name: String let weight: Int let food: String } struct Cat { let name: String let weight: Int let food: String }
对应JSON数据:
{ "catName": "fluffy", "dogName": "softy", "cat": { "food": "fancyFeast", "weight": "8" }, "dog": { "food": "kibble", "weight": "9" } }
解决方案
通过完善CodingKeys定义、自定义解码逻辑,并处理字符串转Int的类型转换,实现属性合并解码:
struct MyPets: Decodable { let dog: Dog let cat: Cat // 定义包含所有需要字段的CodingKeys enum CodingKeys: String, CodingKey { case dog, cat, catName, dogName } public init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) // 解码顶层的宠物名称 let catName = try container.decode(String.self, forKey: .catName) let dogName = try container.decode(String.self, forKey: .dogName) // 临时结构体用于解码嵌套对象中的字符串类型weight struct TempPet: Decodable { let food: String let weight: String } // 解码嵌套的cat和dog临时对象 let tempCat = try container.decode(TempPet.self, forKey: .cat) let tempDog = try container.decode(TempPet.self, forKey: .dog) // 将字符串weight转换为Int,转换失败则抛出解码错误 guard let catWeight = Int(tempCat.weight), let dogWeight = Int(tempDog.weight) else { throw DecodingError.dataCorruptedError( forKey: .cat, in: container, debugDescription: "weight字段无法转换为整数类型" ) } // 合并属性构建最终的Cat和Dog实例 self.cat = Cat(name: catName, weight: catWeight, food: tempCat.food) self.dog = Dog(name: dogName, weight: dogWeight, food: tempDog.food) } } struct Dog { let name: String let weight: Int let food: String } struct Cat { let name: String let weight: Int let food: String }
关键说明
- 完整CodingKeys:必须包含
catName、dogName、cat、dog四个键,才能从解码器容器中获取所有需要的解码数据。 - 类型转换处理:JSON中
weight是字符串类型,通过临时结构体先解码为字符串,再转换为Cat/Dog所需的Int类型,避免类型不匹配报错。 - 属性合并:将顶层名称与嵌套对象的属性结合,直接构建目标结构体实例,逻辑清晰且易维护。
内容的提问来源于stack exchange,提问作者Turnipdabeets
相关产品推荐
相关产品推荐

