How to convert a date string with optional fractional seconds using Codable in Swift?

You can use two different date formatters (with and without fraction seconds) and create a custom DateDecodingStrategy. In case of failure when parsing the date returned by the API you can throw a DecodingError as suggested by @PauloMattos in comments: iOS 9, macOS 10.9, tvOS 9, watchOS 2, Xcode 9 or later The custom ISO8601 … Read more

Codable enum with default case in Swift 4

You can extend your Codable Type and assign a default value in case of failure: enum Type: String { case text, image, document, profile, sign, inputDate = “input_date”, inputText = “input_text” , inputNumber = “input_number”, inputOption = “input_option”, unknown } extension Type: Codable { public init(from decoder: Decoder) throws { self = try Type(rawValue: decoder.singleValueContainer().decode(RawValue.self)) … Read more

Using codable with value that is sometimes an Int and other times a String

struct GeneralProduct: Codable { var price: Double? var id: String? var name: String? private enum CodingKeys: String, CodingKey { case price = “p”, id = “i”, name = “n” } init(price: Double? = nil, id: String? = nil, name: String? = nil) { self.price = price self.id = id self.name = name } init(from decoder: … Read more

Encode nil value as null with JSONEncoder

Yes, but you’ll have to write your own encode(to:) implementation, you can’t use the auto-generated one. struct Foo: Codable { var string: String? = nil var number: Int = 1 func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(number, forKey: .number) try container.encode(string, forKey: .string) } } Encoding an optional directly … 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

Codable class does not conform to protocol Decodable

The compiler cannot synthesise the required init(from:) method due to the weak reference, so you need to write it yourself. class Bookmark: Codable { weak var publication: Publication? var indexPath: [Int] var locationInText = 0 private enum CodingKeys: String, CodingKey { case indexPath case locationInText } init(publication: Publication?, indexPath: [Int]) { self.publication = publication self.indexPath … Read more

How do I use custom keys with Swift 4’s Decodable protocol?

Manually customising coding keys In your example, you’re getting an auto-generated conformance to Codable as all your properties also conform to Codable. This conformance automatically creates a key type that simply corresponds to the property names – which is then used in order to encode to/decode from a single keyed container. However one really neat … Read more

How can I use Swift’s Codable to encode into a dictionary?

If you don’t mind a bit of shifting of data around you could use something like this: extension Encodable { func asDictionary() throws -> [String: Any] { let data = try JSONEncoder().encode(self) guard let dictionary = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any] else { throw NSError() } return dictionary } } Or an … 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