Swift Codable как использовать Any type?

Когда я пытаюсь получить доступ к значению «значение», например, чтобы использовать его в label.text, я получаю сообщение об ошибке

Невозможно присвоить значение типа MyValue? набрать "String?"

Когда я печатаю значение на терминале, он говорит ...

неизвестный контекст по адресу 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)
        }
    }
}

person Drashti Javiya    schedule 11.09.2019    source источник
comment
Похоже, заголовок вообще не соответствует тексту вопроса. Ты можешь починить это?   -  person user28434'mstep    schedule 11.09.2019
comment
Покажите свой код, в котором вы присваиваете myValue некоторому атрибуту   -  person Kamran    schedule 11.09.2019


Ответы (2)


Вы можете получить строковые значения для своей метки, следуя протоколу 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
person Amyth    schedule 11.09.2019

Чтобы получить связанные значения в перечислении, вы можете добавить два вычисленных свойства в 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 }
person vadian    schedule 11.09.2019