Created
May 17, 2019 10:07
-
-
Save natanrolnik/217150f03a6fdad995ec026b898a5975 to your computer and use it in GitHub Desktop.
Code samples for the blog post at https://blog.natanrolnik.me/codable-enums-associated-values
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension EventConfirmationResponse: Codable {} | |
//type 'EventConfirmationResponse' does not conform to protocol 'Decodable' | |
//protocol requires initializer 'init(from:)' with type '(from: Decoder)' | |
//type 'EventConfirmationResponse' does not conform to protocol 'Codable' | |
//protocol requires function 'encode(to:)' with type '(Encoder) throws -> ()' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//declare which keys in the JSON we are interested in | |
enum CodingKeys: String, CodingKey { | |
case status | |
case confirmedUsers | |
case position | |
case reason | |
} | |
//declare the possible values os the status key | |
private enum EventConfirmationStatus: String, Codable { | |
case confirmed | |
case waitlist | |
case notAllowed = "not allowed" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension EventConfirmationResponse: Decodable { | |
init(from decoder: Decoder) throws { | |
//access the keyed container | |
let container = try decoder.container(keyedBy: CodingKeys.self) | |
//decode the value for the status key into the EventConfirmationStatus enum | |
let status = try container.decode(EventConfirmationStatus.self, forKey: .status) | |
//iterate over the received status, and try to decode the other relevant values | |
switch status { | |
case .confirmed: | |
let users = try container.decode([User].self, forKey: .confirmedUsers) | |
self = .confirmed(users) | |
case .waitlist: | |
let users = try container.decode([User].self, forKey: .confirmedUsers) | |
let position = try container.decode(Int.self, forKey: .position) | |
self = .waitlist(position, users) | |
case .notAllowed: | |
let reason = try container.decode(String.self, forKey: .reason) | |
self = .notAllowed(reason) | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension EventConfirmationResponse: Encodable { | |
func encode(to encoder: Encoder) throws { | |
//access the keyed container | |
var container = encoder.container(keyedBy: CodingKeys.self) | |
//iterate over self and encode (1) the status and (2) the associated value(s) | |
switch self { | |
case .confirmed(let users): | |
try container.encode(EventConfirmationStatus.confirmed, forKey: .status) | |
try container.encode(users, forKey: .confirmedUsers) | |
case .waitlist(let position, let users): | |
try container.encode(EventConfirmationStatus.waitlist, forKey: .status) | |
try container.encode(users, forKey: .confirmedUsers) | |
try container.encode(position, forKey: .position) | |
case .notAllowed(let reason): | |
try container.encode(EventConfirmationStatus.notAllowed, forKey: .status) | |
try container.encode(reason, forKey: .reason) | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
switch confirmationResponse { | |
case .confirmed(let users): | |
let confirmedEventVC = ConfirmedEventViewController(event: event, confirmed: users) | |
present(confirmedEventVC, animated: true) | |
case .waitlist(let position, let users): | |
let eventWaitlistVC = EventWaitlistViewController(event: event, position: position, confirmed: users) | |
present(eventWaitlistVC, animated: true) | |
case .notAllowed(let reason): | |
presentNotAllowedAlert(with: reason) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
enum EventConfirmationResponse { | |
case confirmed([User]) //Contains an array of users going to the event | |
case waitlist(Int, [User]) //Contains the position in the waitlist and | |
case notAllowed(String) //Contains the reason why the user is not allowed | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
struct EventConfirmationResponse { | |
let status: String | |
let confirmedUsers: [User]? | |
let position: Int? | |
let reason: String? | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//1 - user is confirmed: | |
{ | |
"status": "confirmed", | |
"confirmedUsers": [ | |
{"id": "abc", "name": "Rachel"}, | |
{"id": "def", "name": "John"} | |
] | |
} | |
//2 - user is in waitlist: | |
{ | |
"status": "waitlist", | |
"position": 12, | |
"confirmedUsers": [ | |
{"id": "abc", "name": "Rachel"}, | |
{"id": "def", "name": "John"} | |
] | |
} | |
//3 - user cannot go for a different reason | |
{ | |
"status": "not allowed", | |
"reason": "It is too late to confirm to this event." | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//in this case, the caller must check for nil for both values | |
func issueRequest<T>(_ request: URLRequest, completion: @escaping (T?, Error?) -> Void) | |
//here, however, it will be either .success or .failure | |
func issueRequest<T>(_ request: URLRequest, completion: @escaping (Result<T, Error>) -> Void) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment