I'm developing a graphical editor in Swift and Cocoa. I need to save and load information about objects in document.
Objects are represented by a 'Node' class and its descendants. They all implement 'Codable' protocol to make it easier to perform serialization. Therefore I need a way to instantiate an object of a proper Node's descendant during deserialization with Decoder.
I use static method 'from' which returns an instance of a Node's descendant according to its NodeType.
However, this leads to lost of boilerplate code in 'from' method.
Are there any ways of instantiating a proper descendant of a class with Codable?
import Cocoa
enum NodeType: Codable {
    case root
    case text
    case lineBreak
}
class Node: Codable {
    let type: NodeType
    let id: UUID
    
    enum CodingKeys: CodingKey {
        case type
        case id
    }
    
    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        self.type = try container.decode(NodeType.self, forKey: .type)
        self.id = try container.decode(UUID.self, forKey: .id)
    }
    
    func encode(to encoder: Encoder) throws {
        var contrainer = encoder.container(keyedBy: CodingKeys.self)
        try contrainer.encode(self.type, forKey: .type)
        try contrainer.encode(self.id, forKey: .id)
    }
    
    static func from(_ decoder: Decoder) throws -> Node {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let type = try container.decode(NodeType.self, forKey: .type)
        switch type {
            case .root:
                return try RootNode(from: decoder)
            case .text:
                return try TextNode(from: decoder)
            case .lineBreak:
                return try LineBreakNode(from: decoder)
        }
    }
}
 
    