How do I make an enum Decodable in Swift?

It’s pretty easy, just use String or Int raw values which are implicitly assigned.

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

image is encoded to 0 and blob to 1

Or

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

image is encoded to "image" and blob to "blob"


This is a simple example how to use it:

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)
}

Update

In iOS 13.3+ and macOS 15.1+ it’s allowed to en-/decode fragments – single JSON values which are not wrapped in a collection type

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)
}

In Swift 5.5+ it’s even possible to en-/decode enums with associated values without any extra code. The values are mapped to a dictionary and a parameter label must be specified for each associated value

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)
}

Leave a Comment