Skip to content

Instantly share code, notes, and snippets.

@bardonadam
Created December 12, 2019 08:11
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bardonadam/4bd267605d9551e327eb70fc23e8132b to your computer and use it in GitHub Desktop.
Save bardonadam/4bd267605d9551e327eb70fc23e8132b to your computer and use it in GitHub Desktop.
Custom decode with SomeKindOfBool
struct Form: Codable, Equatable {
let id: Int
let type: FType
let name: String
let code: String
let hasScreenshot: Bool
let total: Int
let totalUnique: Int
let opened: Int
@SomeKindOfBool var active: Bool
let conversion: Double
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
self.id = try values.decode(Int.self, forKey: .id)
self.type = try values.decode(FType.self, forKey: .type)
self.name = try values.decode(String.self, forKey: .name)
self.code = try values.decode(String.self, forKey: .code)
if let hasScreenshot = try? values.decode(Bool.self, forKey: .hasScreenshot) {
self.hasScreenshot = hasScreenshot
}
else {
let hasScreenshot = try values.decode(Int.self, forKey: .hasScreenshot)
self.hasScreenshot = hasScreenshot != 0
}
self.total = try values.decode(Int.self, forKey: .total)
self.totalUnique = try values.decode(Int.self, forKey: .totalUnique)
self.opened = try values.decode(Int.self, forKey: .opened)
self.conversion = try values.decode(Double.self, forKey: .conversion)
self.active = try values.decode(Bool.self, forKey: .active) // gives me compiler error 'self' used before all stored properties are initialized
// if let active = try? values.decode(Bool.self, forKey: .active) {
// self.active = active
// }
// else {
// let activeInt = try values.decode(Int.self, forKey: .active)
// self.active = activeInt == 1 ? true : false
// }
}
@propertyWrapper
struct SomeKindOfBool: Codable, Equatable {
var wrappedValue: Bool
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let stringifiedValue = try? container.decode(String.self) {
switch stringifiedValue.lowercased() {
case "false": wrappedValue = false
case "true": wrappedValue = true
default: throw APIError.decodingFailure
}
} else if let integerifiedValue = try? container.decode(Int.self) {
switch integerifiedValue {
case 0: wrappedValue = false
case 1: wrappedValue = true
default: throw APIError.decodingFailure
}
} else {
wrappedValue = try container.decode(Bool.self)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment