Using Custom Enum to Map JSON in Swift

Muhammad Muizzsuddin
2 min readAug 27, 2019

--

API consuming application is widely popular today. Most server API provides us, the client, with JSON interface to talk with them. Thanks to Codable in Swift. We can map JSON object to Swift object without third-party library.

Sometimes, the JSON value is enumeration. Which is, you’ll only need fixed number of values and it’s always best to put them in enumeration. For example, we will use Day as example.

// The json object
{
"id: 0,
"day": "Sunday"
}

The backend team chooses to use String rather than Int to make clear that it is a Day enumeration not Date.

Its trivial to just map the JSON object using this type

struct Booking: Codable {
let id: Int
let day: String
}

And we work with the day using equality or switch.

if booking.day == "Sunday"
else if booking.day ...

Or like this.

struct Booking {
let id: Int
let day: Day
}
extension Booking: Codable {
enum CodingKeys: String, CodingKey {
case id, day
}
init(from decoder: Decoder) trhows {
// Do map by hand
}
func encode(to encoder: Encoder) throws {
// encode by hand
}
}

Nice. But there’s a better solution. We want to make compiler perform typecheck. Or, say, it is strongly typed across the whole apps. And the Day is self-contained. Say, if it also used in another type.

Let’s see.

struct Booking: Codable {
let id: Int
let day: Day
}
enum Day: Codable {
case sunday
case monday
...
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
switch try container.decode(String.self) {
case "Sunday": self = .sunday
case ...
default: fatalError()
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
switch self {
case .sunday: try container.encode("Sunday")
default: fatalError()
}
}
}

The key is to use Encoder.singleValueContainer method.

As Apple Documentation says

Returns an encoding container appropriate for holding a single primitive value.

Now that you have known this feature, you may start to refactor your code. Happy coding!

Ahh, sure you can improve this code.

--

--

No responses yet