Reputation: 4462
Is there a way to get list of variables and function of a class?
For example: If my class is like below
class Person {
var age: Int!
var name: String!
func isOlder(from person: Person) -> Bool { }
func hasSameName(as person: Person) -> Bool { }
}
I want to get 2 lists:
1. [age, name]
2. [isOlder( _ : ), hasSameName( _ : )]
Or something similar.
Thanks
Upvotes: 10
Views: 6157
Reputation: 2699
Code refactor for @Anton Plebanovich's answer
func printMethodNamesForClassNamed(classname: String) {
// NSClassFromString() is declared to return AnyClass!, but should be AnyClass?
let maybeClass: AnyClass? = NSClassFromString(classname)
if let cls: AnyClass = maybeClass {
printMethodNamesForClass(cls: cls)
} else {
print("\(classname): no such class")
}
}
func printMethodNamesForClass(cls: AnyClass) {
var methodCount: UInt32 = 0
let methodList = class_copyMethodList(cls, &methodCount)
if let methodList = methodList{
let arr = Array(arrayLiteral: methodList)
for (i, m) in arr.enumerated(){
let name: String = methodName(m: m.pointee) ?? "Not Known"
print("#\(i): \(name)")
}
free(methodList)
}
}
func methodName(m: Method) -> String? {
let sel = method_getName(m)
let nameCString = sel_getName(sel)
return String(cString: nameCString)
}
Upvotes: 0
Reputation: 1516
Swift 4:
func printMethodNamesForClass(cls: AnyClass) {
var methodCount: UInt32 = 0
let methodList = class_copyMethodList(cls, &methodCount)
if let methodList = methodList, methodCount > 0 {
enumerateCArray(array: methodList, count: methodCount) { i, m in
let name = methodName(m: m) ?? "unknown"
print("#\(i): \(name)")
}
free(methodList)
}
}
func enumerateCArray<T>(array: UnsafePointer<T>, count: UInt32, f: (UInt32, T) -> Void) {
var ptr = array
for i in 0..<count {
f(i, ptr.pointee)
ptr = ptr.successor()
}
}
func methodName(m: Method) -> String? {
let sel = method_getName(m)
let nameCString = sel_getName(sel)
return String(cString: nameCString)
}
func printMethodNamesForClassNamed(classname: String) {
// NSClassFromString() is declared to return AnyClass!, but should be AnyClass?
let maybeClass: AnyClass? = NSClassFromString(classname)
if let cls: AnyClass = maybeClass {
printMethodNamesForClass(cls: cls)
} else {
print("\(classname): no such class")
}
}
Upvotes: 11
Reputation: 11567
In Objective C
#import <objc/runtime.h>
getDetailsOfClass(Class clz) {
unsigned int methodCount = 0;
Method *methods = class_copyMethodList(clz, &methodCount);
printf("Found %d methods on '%s'\n", methodCount, class_getName(clz));
for (unsigned int i = 0; i < methodCount; i++) {
Method method = methods[i];
printf("\t'%s' has method named '%s' of encoding '%s'\n",
class_getName(clz),
sel_getName(method_getName(method)),
method_getTypeEncoding(method));
}
free(methods);
}
Invoke: getDetailsOfClass(class)
In Swift
Follow the SO Post. Have implemented same and found success.
To get Method names:
func printMethodNamesForClass(cls: AnyClass) {
var methodCount: UInt32 = 0
let methodList = class_copyMethodList(cls, &methodCount)
if methodList != nil && methodCount > 0 {
enumerateCArray(methodList, methodCount) { i, m in
let name = methodName(m) ?? "unknown"
println("#\(i): \(name)")
}
free(methodList)
}
}
func enumerateCArray<T>(array: UnsafePointer<T>, count: UInt32, f: (UInt32, T) -> ()) {
var ptr = array
for i in 0..<count {
f(i, ptr.memory)
ptr = ptr.successor()
}
}
func methodName(m: Method) -> String? {
let sel = method_getName(m)
let nameCString = sel_getName(sel)
return String.fromCString(nameCString)
}
func printMethodNamesForClassNamed(classname: String) {
// NSClassFromString() is declared to return AnyClass!, but should be AnyClass?
let maybeClass: AnyClass? = NSClassFromString(classname)
if let cls: AnyClass = maybeClass {
printMethodNamesForClass(cls)
}
else {
println("\(classname): no such class")
}
}
Happy Coding..
Upvotes: 5
Reputation: 233
I believe you can use Mirror
API for this:
https://developer.apple.com/documentation/swift/mirror
New key-path API in Swift 4 might also be helpful: https://github.com/apple/swift-evolution/blob/master/proposals/0161-key-paths.md
Upvotes: 1