Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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 -> ()'
//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"
}
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)
}
}
}
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)
}
}
}
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)
}
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
}
struct EventConfirmationResponse {
let status: String
let confirmedUsers: [User]?
let position: Int?
let reason: String?
}
//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."
}
//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
You can’t perform that action at this time.