Get all the keys for a class

1.2k views Asked by At

Recently I work with the function func setValue(_ value: AnyObject?, forKey key: String) of the NSKeyValueCoding protocol to change the text color of a UIPickerDate in the following way:

class ColoredDatePicker: UIDatePicker {

    var changed = false

    override func addSubview(view: UIView) {
       if !changed {
          changed = true
          self.setValue(UIColor(red: 0.42, green: 0.42, blue: 0.42, alpha: 1), forKey: "textColor")

       }
       super.addSubview(view)
    }
}

Regarding the answer in this question. It works perfectly.

But my answer here is:

How do I know what names that the class provide like the textColor used above?.

I'm trying to find anything get all the names or in the documentation, but so far I don't find anything yet to get the keys provided by a class like in the above case.

3

There are 3 answers

1
Adam Finley On BEST ANSWER

The objective-c runtime provides this type of reflection for properties:

id UIDatePickerClass = objc_getClass("UIDatePicker");
unsigned int outCount, i;
objc_property_t *properties = class_copyPropertyList(UIDatePickerClass, &outCount);
for (i = 0; i < outCount; i++) {
    objc_property_t property = properties[i];
    fprintf(stdout, "%s %s\n", property_getName(property), property_getAttributes(property));
}

reference doc: https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ObjCRuntimeRef/index.html#//apple_ref/c/func/class_copyPropertyList

edit - swift has basic reflection too: https://stackoverflow.com/a/24069875/1385467

0
Victor Sigler On

For those we want a Swift solution like the @Adam, here is :

var propertiesCount : CUnsignedInt = 0
let propertiesInAClass  = class_copyPropertyList(UIDatePicker.self, &propertiesCount)
var propertiesDictionary : NSMutableDictionary = NSMutableDictionary()

for var i = 0; i < Int(propertiesCount); i++ {
    var property = propertiesInAClass[i]
    var propName = NSString(CString: property_getName(property), encoding: NSUTF8StringEncoding)
    println(propName)
}

Swift 4.1:

var propertiesCount: CUnsignedInt = 0
let propertiesInAClass = class_copyPropertyList(UIDatePicker.self, &propertiesCount)!
var propertiesDictionary: NSMutableDictionary = [:]

for i in 0..<propertiesCount {
    var property = propertiesInAClass[Int(i)]
    let propName = NSString(cString: property_getName(property), encoding: String.Encoding.utf8.rawValue)
    print(propName)
}
0
Atka On

Some changes to @Victor Sigler & @dwlz, to get current values for all keys:

    var propertiesCount : CUnsignedInt = 0
    let propertiesInClass = class_copyPropertyList(UIDatePicker.self, &propertiesCount)
    print("Prperties:\(propertiesCount)")
    for i in 0..<propertiesCount
    {
        let property = propertiesInClass![Int(i)]
        let name = NSString(cString: property_getName(property), encoding: String.Encoding.utf8.rawValue)
        print("\(i + 1). Key:\(name!),value \(String(describing: self.value(forKey: name! as String)))")
    }