Swift Codable如何使用Any类型?

时间:2019-09-11 11:58:39

标签: swift codable decodable

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

  

无法分配类型为“ MyValue?”的值键入“字符串?”

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

  

未知上下文(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)
        }
    }
}

2 个答案:

答案 0 :(得分:0)

要获取枚举中的关联值,可以在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
}

或者像value方法一样打开encode

 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 }

答案 1 :(得分:0)

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

<body>
  <blockquote class="twitter-tweet">
    <a href="https://twitter.com/i/status/495719809695621121"></a>
  </blockquote>
</body>