Swift Codable如何使用Any类型?

Swift Codable how to use Any type?

当我尝试访问 "value" 的值(例如在 label.text 中使用它时),出现错误

Cannot assign value of type 'MyValue?' to type 'String?'

当我将值打印到终端时,它说...

unknown context at 0x109d06188).MyValue.string...

如何解决这个问题?

struct Root: Codable {
    let description,id: String
    let group,groupDescription: String?
    let name: String
    let value: MyValue

    enum CodingKeys: String, CodingKey {
        case description = "Description"
        case group = "Group"
        case groupDescription = "GroupDescription"
        case id = "Id"
        case name = "Name"
        case value = "Value"
    }
}

enum MyValue: Codable {
    case string(String)
    case innerItem(InnerItem)

    init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        if let x = try? container.decode(String.self) {
            self = .string(x)
            return
        }
        if let x = try? container.decode(InnerItem.self) {
            self = .innerItem(x)
            return
        }
        throw DecodingError.typeMismatch(MyValue.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for MyValue"))
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        switch self {
        case .string(let x):
            try container.encode(x)
        case .innerItem(let x):
            try container.encode(x)
        }
    }
}

要获取枚举中的关联值,您可以在 MyValue

中添加两个计算属性
var stringValue : String? {
    guard case .string(let string) = self else { return nil }
    return string
}

var innerItemValue : InnerItem? {
    guard case .innerItem(let innerItem) = self else { return nil }
    return innerItem
}

或者像 encode 方法那样打开 value

 switch root.value {
    case .string(let string): // do something with `string`
    case .innerItem(let innerItem):  // do something with `innerItem`
 }

或者直接使用if case

if case .string(let string) = root.value { someLabel.text = string }

您可以通过遵守 rawRepresentable 协议获取标签的字符串值:

enum MyValue: Codable, RawRepresentable {


var rawValue: String {
    switch self {
    case .string(let stringVal):
        return stringVal
    case .innerItem(let myVal):
        return String(describing: myVal)
    }
}

typealias RawValue = String

init?(rawValue: String) {
    return nil
}



case string(String)
case innerItem(InnerItem)

}

let myVal = MyValue.string("testString")
var strVal: String = myVal.rawValue // testString