我有一个需要符合“可编码”的结构。结构本身必须有一个对象,该对象也可以符合“可编码”。但是,这会阻止结构符合“可编码”本身。
例子:
import Foundation
struct SignalRMessageBroadcastRequest: Codable {
let method: String?
let message: Codable
let group: String?
}
我在这里缺少什么可以允许这种行为吗?
编辑:
正如@Sweeper 指出的那样,在编译时不知道类型message
是什么。所以我必须提供自定义编码/解码逻辑,以便可以在运行时解决。为此,我使用“方法”字符串的值来尝试对不同模型进行编码/解码。我想您也可以按顺序尝试不同的模型,直到其中一个起作用。
解决方案:
struct SignalRMessageBroadcastRequest: Codable {
let method: String
let group: String?
let message: Codable
enum CodingKeys: CodingKey {
case method, message, group
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
method = try container.decode(String.self, forKey: .method)
group = try container.decode(String?.self, forKey: .group)
if method == "method1" {
message = try container.decode(PossibleObject1.self, forKey: .message)
} else if method == "method2" {
message = try container.decode(PossibleObject2.self, forKey: .message)
} else {
throw DecodingError.dataCorruptedError(forKey: .method, in: container, debugDescription: "no suitable config type found for method \(method)!")
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(method, forKey: .method)
try container.encode(group, forKey: .method)
if method == "method1" {
try container.encode(message as? PossibleObject1, forKey: .message)
} else if method == "method2" {
try container.encode(message as? PossibleObject2, forKey: .message)
}
}
}