Skip to content

Instantly share code, notes, and snippets.

@possen
Created June 30, 2019 18:44
Show Gist options
  • Save possen/d944a26c4f724f8836eba41bff3a5d43 to your computer and use it in GitHub Desktop.
Save possen/d944a26c4f724f8836eba41bff3a5d43 to your computer and use it in GitHub Desktop.
import Foundation
let confirmedJsonString = """
{
"title": "Confirmed",
"status": "confirmed",
"confirmedUsers": [
{"id": "abc", "name": "Rachel"},
{"id": "def", "name": "John"}
]
}
"""
let waitlistJsonString = """
{
"title": "Wait list",
"status": "waitlist",
"position": 12,
"confirmedUsers": [
{"id": "ghi", "name": "Martin"},
{"id": "jkl", "name": "Michelle"}
]
}
"""
let notAllowedJsonString = """
{
"title": "Not Allowed",
"status": "not allowed",
"reason": "It is too late to confirm to this event."
}
"""
let badStatusJSONString = """
{
"title": "Bad",
"status": "some bad status"
}
"""
struct User: Codable {
let id: String
let name: String
}
struct Response: Codable {
let title: String
let status: State
}
enum State {
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
}
extension State: CustomDebugStringConvertible {
var debugDescription: String {
switch self {
case .confirmed(let users):
return "Confirmed. Confirmed users are \(users.map { $0.name }.joined(separator: ", ") )"
case .waitlist(let position, let users):
return "Position \(position) at waitlist. Confirmed users are \(users.map { $0.name }.joined(separator: ", ") )"
case .notAllowed(let reason):
return "Not allowed. Reason is: \(reason)"
}
}
}
extension State: Codable {
//declare which keys we are interested in
private enum CodingKeys: String, CodingKey {
case status
case confirmedUsers
case position
case reason
case title
}
//declare the possible values os the status key
private enum EventConfirmationStatus: String, Codable {
case confirmed
case waitlist
case notAllowed = "not allowed"
}
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)
}
}
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)
}
}
}
func decodeToConfirmationDescription(from jsonString: String) -> String {
do {
let confirmation = try JSONDecoder().decode(Response.self,
from: jsonString.data(using: .utf8)!)
return String(reflecting: confirmation) //this uses the CustomDebugStringConvertible implemented above
} catch {
return "Couldn't decode \(jsonString) into State. Error: \(error)"
}
}
print(decodeToConfirmationDescription(from: confirmedJsonString))
print(decodeToConfirmationDescription(from: waitlistJsonString))
print(decodeToConfirmationDescription(from: notAllowedJsonString))
print(decodeToConfirmationDescription(from: badStatusJSONString))
print("helelo")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment