Skip to content

Instantly share code, notes, and snippets.

@cprovatas
Created January 19, 2018 23:05
Show Gist options
  • Save cprovatas/6e7400577984d60a0dbcaeddd009b228 to your computer and use it in GitHub Desktop.
Save cprovatas/6e7400577984d60a0dbcaeddd009b228 to your computer and use it in GitHub Desktop.
Auto-implement class/struct as envelope for top level arrays in JSON by implementing this simple protocol
protocol TopLevelCollection: Codable {
associatedtype ElementType: Codable
var elements: [ElementType] { get set }
init(elements: [ElementType])
}
extension TopLevelCollection {
public init(from decoder: Decoder) throws {
var container = try decoder.unkeyedContainer()
var elements: [ElementType] = []
while !container.isAtEnd {
let subdecoder = try container.superDecoder()
let subcontainer = try subdecoder.singleValueContainer()
let element = try subcontainer.decode(ElementType.self)
elements.append(element)
}
self.init(elements: elements)
}
func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(contentsOf: elements)
}
}
/// USAGE:
struct Foo: TopLevelCollection {
var elements: [String]
}
// ["foo", "bar", "blah"] JSON will now be mapped to 'elements' and will be encoded back into the same format
struct Bar: TopLevelCollection {
var elements: [BarCodable]
}
struct BarCodable: Codable {
let name: String
}
/// [ { "name": "Jerry" }, { "name": "Bob" } ] will be mapped to 'Bar''s elements and vice-versa
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment