小编典典

如何在 Swift 中使枚举可解码?

all

enum PostType: Decodable {

    init(from decoder: Decoder) throws {

        // What do i put here?
    }

    case Image
    enum CodingKeys: String, CodingKey {
        case image
    }
}

我要做什么来完成这个?另外,假设我将其更改case为:

case image(value: Int)

我如何使它符合可解码?

这是我的完整代码(不起作用)

let jsonData = """
{
    "count": 4
}
""".data(using: .utf8)!

        do {
            let decoder = JSONDecoder()
            let response = try decoder.decode(PostType.self, from: jsonData)

            print(response)
        } catch {
            print(error)
        }
    }
}

enum PostType: Int, Codable {
    case count = 4
}

另外,它将如何处理这样的枚举?

enum PostType: Decodable {
    case count(number: Int)
}

阅读 59

收藏
2022-06-10

共1个答案

小编典典

这很容易,只需使用隐式分配的原始值StringInt

enum PostType: Int, Codable {
    case image, blob
}

image被编码为0blob``1

或者

enum PostType: String, Codable {
    case image, blob
}

image被编码为"image"blob``"blob"


这是一个如何使用它的简单示例:

enum PostType : Int, Codable {
    case count = 4
}

struct Post : Codable {
    var type : PostType
}

let jsonString = "{\"type\": 4}"

let jsonData = Data(jsonString.utf8)

do {
    let decoded = try JSONDecoder().decode(Post.self, from: jsonData)
    print("decoded:", decoded.type)
} catch {
    print(error)
}

更新

在 iOS 13.3+ 和 macOS 15.1+ 中,它允许编码/解码 片段 ——未包装在集合类型中的单个 JSON 值

let jsonString = "4"

let jsonData = Data(jsonString.utf8)
do {
    let decoded = try JSONDecoder().decode(PostType.self, from: jsonData)
    print("decoded:", decoded) // -> decoded: count
} catch {
    print(error)
}

在 Swift 5.5+ 中,甚至可以使用关联值对枚举进行
en-/decode,而无需任何额外代码。这些值被映射到一个字典,并且必须为每个关联的值指定一个参数标签

enum Rotation: Codable {
    case zAxis(angle: Double, speed: Int)
}

let jsonString = #"{"zAxis":{"angle":90,"speed":5}}"#

let jsonData = Data(jsonString.utf8)
do {
    let decoded = try JSONDecoder().decode(Rotation.self, from: jsonData)
    print("decoded:", decoded)
} catch {
    print(error)
}
2022-06-10