0

我有一个需要符合“可编码”的结构。结构本身必须有一个对象,该对象也可以符合“可编码”。但是,这会阻止结构符合“可编码”本身。

例子:

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)
        }
    }
}
4

0 回答 0