如何手动解码一组遵循自定义LogicBlock协议的Codable元素数组
核心解决思路
你只需要先解码出每个LogicBlock对象的typeID字段,匹配到对应的枚举值后,再用对应的具体结构体类型解码整个对象即可,完整实现如下:
1. 先定义通用CodingKey读取typeID
private enum CommonLogicBlockCodingKeys: String, CodingKey { case typeID }
2. 实现类型判断与解码逻辑
修正你的decodeLogicBlock方法:
private static func decodeLogicBlock(from decoder: Decoder) throws -> LogicBlock { // 先读取typeID判断具体类型 let container = try decoder.container(keyedBy: CommonLogicBlockCodingKeys.self) let typeID = try container.decode(LogicBlockTypeID.self, forKey: .typeID) switch typeID { case .a: return try Struct1(from: decoder) case .b: return try Struct2(from: decoder) case .c: // 注意你原代码中第三个结构体和Struct2重名,需修改为Struct3 return try Struct3(from: decoder) } }
3. 修正MyModel的解码实现
struct MyModel: Codable { var var1: String var var2: Int var logicBlocks: [LogicBlock] enum CodingKeys: String, CodingKey { case var1, var2, logicBlocks } init(from decoder: Decoder) throws { let rootContainer = try decoder.container(keyedBy: CodingKeys.self) // 解码普通属性 var1 = try rootContainer.decode(String.self, forKey: .var1) var2 = try rootContainer.decode(Int.self, forKey: .var2) // 解码logicBlocks数组 var blocksContainer = try rootContainer.nestedUnkeyedContainer(forKey: .logicBlocks) var parsedBlocks = [LogicBlock]() while !blocksContainer.isAtEnd { let blockDecoder = try blocksContainer.superDecoder() parsedBlocks.append(try Self.decodeLogicBlock(from: blockDecoder)) } logicBlocks = parsedBlocks } // 若需要支持编码功能,需补充实现encode方法 func encode(to encoder: Encoder) throws { var rootContainer = encoder.container(keyedBy: CodingKeys.self) try rootContainer.encode(var1, forKey: .var1) try rootContainer.encode(var2, forKey: .var2) var blocksContainer = rootContainer.nestedUnkeyedContainer(forKey: .logicBlocks) try logicBlocks.forEach { block in try block.encode(to: blocksContainer.superEncoder()) } } }
注意事项
- 你原代码中第三个遵循LogicBlock协议的结构体和Struct2重名,需要修改为独立命名比如Struct3,否则会触发编译错误
- 如果后续新增LogicBlock的实现类型,只需要在
decodeLogicBlock的switch分支中新增对应typeID的处理逻辑即可 - 该方案要求服务端返回的每个LogicBlock对象中必须携带正确的
typeID字段,值与你定义的LogicBlockTypeID枚举的rawValue对应即可
内容的提问来源于stack exchange,提问作者HazzaOb
相关产品推荐
相关产品推荐

