What is difference between optional and decodeIfPresent when using Decodable for JSON Parsing?

There’s a subtle, but important difference between these two lines of code: // Exhibit 1 foo = try container.decode(Int?.self, forKey: .foo) // Exhibit 2 foo = try container.decodeIfPresent(Int.self, forKey: .foo) Exhibit 1 will parse: { “foo”: null, “bar”: “something” } but not: { “bar”: “something” } while exhibit 2 will happily parse both. So in … Read more

Swift Codable multiple types

You can try struct Root: Codable { let description,id: String let group,groupDescription: String? let name: String let value: MyValue enum CodingKeys: String, CodingKey { case description = “Description” case group = “Group” case groupDescription = “GroupDescription” case id = “Id” case name = “Name” case value = “Value” } } enum MyValue: Codable { case … Read more

How to use Any in Codable Type

Quantum Value First of all you can define a type that can be decoded both from a String and Int value. Here it is. enum QuantumValue: Decodable { case int(Int), string(String) init(from decoder: Decoder) throws { if let int = try? decoder.singleValueContainer().decode(Int.self) { self = .int(int) return } if let string = try? decoder.singleValueContainer().decode(String.self) { … Read more

Swift JSONDecode decoding arrays fails if single element decoding fails

One option is to use a wrapper type that attempts to decode a given value; storing nil if unsuccessful: 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) } } We can then decode an array of these, with your … Read more

With JSONDecoder in Swift 4, can missing keys use a default value instead of having to be optional properties?

You can implement the init(from decoder: Decoder) method in your type instead of using the default implementation: class MyCodable: Codable { var name: String = “Default Appleseed” required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) if let name = try container.decodeIfPresent(String.self, forKey: .name) { self.name = name } } } You … Read more

Using Decodable in Swift 4 with Inheritance

I believe in the case of inheritance you must implement Coding yourself. That is, you must specify CodingKeys and implement init(from:) and encode(to:) in both superclass and subclass. Per the WWDC video (around 49:28, pictured below), you must call super with the super encoder/decoder. required init(from decoder: Decoder) throws { // Get our container for … Read more

How to decode a property with type of JSON dictionary in Swift [45] decodable protocol

With some inspiration from this gist I found, I wrote some extensions for UnkeyedDecodingContainer and KeyedDecodingContainer. You can find a link to my gist here. By using this code you can now decode any Array<Any> or Dictionary<String, Any> with the familiar syntax: let dictionary: [String: Any] = try container.decode([String: Any].self, forKey: key) or let array: … Read more