Let's start with the problem I'm trying to solve. I'm parsing an XML document into a hierarchy of model objects. All of the model objects have a common base class with a set of common properties. Then each specific model class has a few additional properties.
Here's a simplified example of a few model classes:
class Base {
    var id: String?
    var name: String?
    var children = [Base]()
}
class General: Base {
    var thing: String?
}
class Specific: General {
    var boring: String?
}
class Other: Base {
    var something: String?
    var another: String?
}
The part I'm having issue with is implementing a clean way to write the XML parser classes to deal with this model hierarchy. I'm attempting to write a parser hierarchy that matches the model hierarchy. Here's my attempt:
protocol ObjectParser {
    associatedtype ObjectType
    func createObject() -> ObjectType
    func parseAttributes(element: XMLElement, object: ObjectType)
    func parseElement(_ element: XMLElement) -> ObjectType
}
class BaseParser: ObjectParser {
    typealias ObjectType = Base
    var shouldParseChildren: Bool {
        return true
    }
    func createObject() -> Base {
        return Base()
    }
    func parseAttributes(element: XMLElement, object: Base) {
        object.id = element.attribute(forName: "id")?.stringValue
        object.name = element.attribute(forName: "name")?.stringValue
    }
    func parseChildren(_ element: XMLElement, parent: Base) {
        if let children = element.children {
            for child in children {
                if let elem = child as? XMLElement, let name = elem.name {
                    var parser: BaseParser? = nil
                    switch name {
                    case "general":
                        parser = GeneralParser()
                    case "specific":
                        parser = SpecificParser()
                    case "other":
                        parser = OtherParser()
                    default:
                        break
                    }
                    if let parser = parser {
                        let res = parser.parseElement(elem)
                        parent.children.append(res)
                    }
                }
            }
        }
    }
    func parseElement(_ element: XMLElement) -> Base {
        let res = createObject()
        parseAttributes(element: element, object: res)
        if shouldParseChildren {
            parseChildren(element, parent: res)
        }
        return res
    }
}
class GeneralParser: BaseParser {
    typealias ObjectType = General
    override func createObject() -> General {
        return General()
    }
    func parseAttributes(element: XMLElement, object: General) {
        super.parseAttributes(element: element, object: object)
        object.thing = element.attribute(forName: "thing")?.stringValue
    }
}
class SpecificParser: GeneralParser {
    typealias ObjectType = Specific
    override func createObject() -> Specific {
        return Specific()
    }
    func parseAttributes(element: XMLElement, object: Specific) {
        super.parseAttributes(element: element, object: object)
        object.boring = element.attribute(forName: "boring")?.stringValue
    }
}
And there is OtherParser which is the same as GeneralParser except replace General with Other. Of course there are many more model objects and associated parsers in my hierarchy.
This version of the code almost works. You'll notice there is no override for the parseAttributes methods in the GeneralParser and SpecificParser classes. I think this is due to the different type for the object argument. The result of this is that the parser specific parseAttributes methods are not being called from the parseElement method of BaseParser. I got around this problem by updating all of the parseAttributes signatures to:
func parseAttributes(element: XMLElement, object: Base)
Then in the non-Base parsers, I had to use a force-cast (and add override such as the following in the GeneralParser:
override func parseAttributes(element: XMLElement, object: Base) {
    super.parseAttributes(element: element, object: object)
    let general = object as! General
    general.thing = element.attribute(forName: "thing")?.stringValue
}
Finally, the question:
How do I eliminate the need for the force-cast in the parseAttributes method hierarchy and make use of the protocol's associated type? And more general, is this the correct approach to this problem? Is there a more "Swift" way to solve this problem?
Here's some made up XML based on this simplified object model if needed:
<other id="top-level" name="Hi">
    <general thing="whatever">
        <specific boring="yes"/>
        <specific boring="probably"/>
        <other id="mid-level">
            <specific/>
        </other>
    </general>
</other>
 
    