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

navigation bar rightbaritem image-button bug iOS 11

Reason The problem appears because from ios 11 UIBarButtonItem uses autolayout instead of dealing with frames. Solution You should add width constraint for this image-button if you use Xcode 9. button.widthAnchor.constraint(equalToConstant: 32.0).isActive = true button.heightAnchor.constraint(equalToConstant: 32.0).isActive = true PS button is not UIBarButtonItem, it is UIButton inside UIBarButtonItem. You should set constraint not for UIBarButtonItem, … Read more

How can I deal with @objc inference deprecation with #selector() in Swift 4?

The fix-it is correct – there’s nothing about the selector you can change in order to make the method it refers to exposed to Objective-C. The whole reason for this warning in the first place is the result of SE-0160. Prior to Swift 4, internal or higher Objective-C compatible members of NSObject inheriting classes were … 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

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

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