dimanche 22 mai 2022

How to get the property names for `UIFont` (and other UIKit classes)?

This simple code:

func getProperties(object: AnyObject) -> [String] {

    var result = [String]()

    let mirror = Mirror(reflecting: object)

    mirror.children.forEach { property in

        guard let label = property.label else {
            return
        }
        result.append(label)
    }

    return result
}

works for custom classes, e.g.:

class A {

    var one: String
    var two: Int

    init() {
        one = "hello"
        two = 1
    }
}

var a = A()
print(getProperties(object: a))
// prints ["one", "two"]

However the same code for UIFont (and other UIKit classes), returns nothing:

var font = UIFont.systemFont(ofSize: 10)
print(getProperties(object: font))
// prints []

I also tried an old-school extension for NSObject:

extension NSObject {

    var propertyNames: [String] {

        var result = [String]()

        let clazz = type(of: self)
        var count = UInt32()

        guard let properties = class_copyPropertyList(clazz, &count) else {
            return result
        }

        for i in 0..<Int(count) {

            let property: objc_property_t = properties[i]

            guard let name = NSString(utf8String: property_getName(property)) else {
                continue
            }
            result.append(name as String)
        }

        return result
    }
}

And again, it works for my custom classes (if they extend NSobject and the properties are marked as @objc):

class B: NSObject {

    @objc var one: String
    @objc var two: Int

    override init() {
        one = "hello"
        two = 1
    }
}

var b = B()
print(b.propertyNames)
// prints ["one", "two"]

but doesn't find any properties for UIFont.

If I look at the UIFont definition, the properties are seems defined like regular properties (or at least this is what Xcode shows:

open class UIFont : NSObject, NSCopying, NSSecureCoding {
//...
    open var familyName: String { get }
    open var fontName: String { get }
    // etc

The type of the class is UICTFont though, not sure if it matters.

I would like to understand why this is not working, but my main question is more generic: is there any way to obtain the properties of the UIKit class (e.g. UIFont)?





Aucun commentaire:

Enregistrer un commentaire