'Mirroring Not Picking Up Base Class on Swift 3

I am building a function that will take an instance of a class object and convert it to an XML request to be sent to a web service. To accomplish this, I am using mirroring to iterate through the key/value pairs in the class. In my testing, I see it is working great, with one major problem, none of the inherited class parameters are coming across. For example, in the code below, the loop is executed three times for "descriptionText, modelNumber and serialNumber, name and uuid are never collected. Is there a way for me to use mirroring and pick up all the parameters of the base class, as well as the widget? Also, if there is a better way to do this, I am all ears.

import UIKit

class BaseObject: NSObject { 
   var name = String()
   var uuid = String()
}

class Widget: BaseObject {
    var descriptionText = String()
    var modelNumber = String()
    var serialNumber = String()
}

var widget1 = Widget()

widget1.name = "Generic Widget"
widget1.uuid = "A guid"
widget1.descriptionText = "Class A Extra Larget Widget"
widget1.modelNumber = "1234"
widget1.serialNumber = "4321"

let widgetMirror = Mirror(reflecting: widget1)

for attr in widgetMirror.children {
    print(attr.label!)
}


Solution 1:[1]

You need to use the superclassMirror: Mirror? property for that. For instance:

for attr in widgetMirror.superclassMirror!.children {
    print(attr.label!)
}

prints the expected results:

name
uuid


Update. If you keep running into this, add this Mirror extension to your toolkit:

extension Mirror {
    var allChildren: [Mirror.Child] {
        var allChildren: [Mirror.Child] = []
        var mirror: Mirror! = self
        repeat {
            allChildren.append(contentsOf: mirror.children)
            mirror = mirror.superclassMirror
        } while mirror != nil
        return allChildren
    }
}

Usage:

for attr in widgetMirror.allChildren {
    print(attr.label!)
}

Solution 2:[2]

A partial answer was already posted, but here is a way to wrap it all up.

var mirror: Mirror? = Mirror(reflecting: widget1)

repeat {
    for (index, child) in mirror!.children.enumerated() {
        print (child.label!)
    }

    mirror = mirror?.superclassMirror
} while mirror != nil

I thought about a bit more. I think this is more Swifty.

extension Mirror {

    var posterity: Children {
        if let superclassMirror = superclassMirror {
            return Children([children, superclassMirror.posterity].joined())
        } else {
            return children
        }
    }

}

let widgetMirror = Mirror(reflecting: widget1)

for child in widgetMirror.posterity {
    print(child.label!)
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2