невозможно преобразовать Enum в строку из Json в Swift - PullRequest
1 голос
/ 15 июня 2019

Я получаю ошибку:

Невозможно инициализировать роль из недопустимого строкового значения Mage

когда я пытался интерпретировать массив строк как тип enum из файла JSON.

struct ChampionsData : Decodable{
    let id : String
    let key : String
    let info : Info
    let tags : [Role]
}

enum Role : String, CaseIterable, Decodable{
    case Tank = "you believe that last person standing wins"
    case Mage = "you like fantacies and tricking people"
    case Assasin = "you enjoy living with danger"
    case Fighter = "you are the warrior that built this town"
    case Support = "you are a reliable teammate that always appears where you are needed "
    case Marksman = "you tend to be the focus of the game, or the reason of victory or loss"

    enum CodingKeys: String, CodingKey {
        case mage = "Mage"
        case assassin = "Assassin"
        case tank = "Tank"
        case fighter = "Fighter"
        case support = "Support"
        case marksman = "Marksman"
    }
}

Как я могу разобрать его в объект JSON, если я хочу интерпретировать теги как массив типа перечисления Role вместо массива строк (или избавиться от ошибки)?

1 Ответ

1 голос
/ 15 июня 2019

Ваш JSON должен быть примерно таким

let jsonString = """
{
"id" :"asda",
"key" : "key asd",
"tags" : [
       "Mage",
       "Marksman"
]
}
"""

ПРИМЕЧАНИЕ: я игнорирую let info : Info здесь.

И из этой строки перечисление должно быть Mage, Marksman .. и так далее

Но вы добавили их, чтобы они были

case Mage = "you like fantacies and tricking people"*

В Enum необработанные значения неявно присваиваются как CodingKeys

Обновите ваш код до

enum Role : String, Decodable {
    case tank = "Tank"
    case mage = "Mage"
    case assasin = "Assassin"
    case fighter = "Fighter"
    case support = "Support"
    case marksman = "Marksman"

    var value: String {
        switch self {
        case .tank:
            return "you believe that last person standing wins"
        case .mage:
            return "you like fantacies and tricking people"
        case .assasin:
            return "you enjoy living with danger"
        case .fighter:
            return "you are the warrior that built this town"
        case .support:
            return "you are a reliable teammate that always appears where you are needed"
        case .marksman:
            return "you tend to be the focus of the game, or the reason of victory or loss"
        }
    }
}

Тогда вы можете просто использовать значение после декодирования, как это

let data = jsonString.data(using: .utf8)!

// Initializes a Response object from the JSON data at the top.
let myResponse = try! JSONDecoder().decode(ChampionsData.self, from: data)

print(myResponse.tags.first?.value as Any)

Если мы использовали json, упомянутый в начале, мы получим

"you like fantacies and tricking people"
...