-
-
Save hamishknight/c6d270f7298e4db9e787aecb5b98bcae to your computer and use it in GitHub Desktop.
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
import Foundation | |
struct FailableDecodable<Base : Decodable> : Decodable { | |
let base: Base? | |
init(from decoder: Decoder) throws { | |
let container = try decoder.singleValueContainer() | |
self.base = try? container.decode(Base.self) | |
} | |
} | |
struct FailableCodableArray<Element : Codable> : Codable { | |
var elements: [Element] | |
init(from decoder: Decoder) throws { | |
var container = try decoder.unkeyedContainer() | |
var elements = [Element]() | |
if let count = container.count { | |
elements.reserveCapacity(count) | |
} | |
while !container.isAtEnd { | |
if let element = try container | |
.decode(FailableDecodable<Element>.self).base { | |
elements.append(element) | |
} | |
} | |
self.elements = elements | |
} | |
func encode(to encoder: Encoder) throws { | |
var container = encoder.singleValueContainer() | |
try container.encode(elements) | |
} | |
} | |
struct ProductsRoot : Codable { | |
var products: [GroceryProduct] | |
init(from decoder: Decoder) throws { | |
let container = try decoder.container(keyedBy: CodingKeys.self) | |
self.products = try container | |
.decode(FailableCodableArray<GroceryProduct>.self, forKey: .products) | |
.elements | |
} | |
} | |
// or... | |
struct ProductsRoot2 : Codable { | |
private let _products: FailableCodableArray<GroceryProduct> | |
var products: [GroceryProduct] { | |
return _products.elements | |
} | |
private enum CodingKeys : String, CodingKey { | |
case _products = "products" | |
} | |
} | |
struct GroceryProduct : Codable { | |
var name: String | |
var points: Int | |
var description: String? | |
} | |
let jsonString = """ | |
{ "products": [ | |
{ | |
"name": "Banana", | |
"points": 200, | |
"description": "A banana grown in Ecuador." | |
}, | |
{ | |
"name": "Orange" | |
} | |
]} | |
""" | |
let jsonData = Data(jsonString.utf8) | |
do { | |
let decoded = try JSONDecoder().decode(ProductsRoot.self, from: jsonData) | |
print(decoded) | |
let decoded2 = try JSONDecoder().decode(ProductsRoot2.self, from: jsonData) | |
print(decoded2) | |
} catch { | |
print(error) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment