swiftextension-methodsinitconvenience-methods

Create a generic Data initializer for Decodable types using Swift


@objcMembers
public class MyResponse: NSObject, Codable {
    public let id: String?
    public let context: String?
    public let results: [MyResult]?
}

What is the proper way to parse MyResponse from Data in class extension?

I tried the following, but got error "Cannot assign to value: 'self' is immutable. Cannot assign value of type 'MyResponse' to type 'Self'."

extension MyResponse {
    public convenience init(data: Data) throws {
        self = try JSONDecoder().decode(MyResponse.self, from: data)
    }
}

Solution

  • You can't overwrite class itself, but you can init it, init object from json and then assign values/ If take your code - it'll be something like this:

    public class MyResponse: Codable {
        public var id: String?
        public var context: String?
        public var results: [MyResult]?
    }
    
    public extension MyResponse {
        convenience init(data: Data) throws {
            self.init()
            let object = try JSONDecoder().decode(MyResponse.self, from: data)
            self.id = object.id
            self.context = object.context
            self.results = object.results
        }
    }
    

    If you really don't need a class it's better to use struct instead of it, and it can be like this:

    public struct MyResponse: Codable {
        public let id: String?
        public let context: String?
        public let results: [String]?
    }
    
    public extension MyResponse {
        init(data: Data) throws {
            self = try JSONDecoder().decode(MyResponse.self, from: data)
        }
    }