Lista de propiedades de la clase en swift

Nota: hay una pregunta similar publicada para el objective c aquí , pero quiero lograrlo rápidamente.

Tengo una clase declarada de la siguiente manera:

import UIKit class EachDayCell : UITableViewCell { @IBOutlet var dateDisplayLabel : UITextField @IBOutlet var nameDisplayLabel : UITextField @IBAction func goToPendingItems(sender : AnyObject) { } @IBAction func showDateSelectionPicker(sender : AnyObject) { } init(style: UITableViewCellStyle, reuseIdentifier: String!) { super.init(style: style, reuseIdentifier: reuseIdentifier) } } 

Ahora quiero obtener una matriz en el alistamiento rápido: dateDisplayLabel, nameDisplayLabel.

¿Cómo puedo conseguir esto?

Usando Mirror

Aquí hay una solución pura de Swift con algunas limitaciones:

 protocol PropertyNames { func propertyNames() -> [String] } extension PropertyNames { func propertyNames() -> [String] { return Mirror(reflecting: self).children.flatMap { $0.label } } } class Person : PropertyNames { var name = "Sansa Stark" var awesome = true } Person().propertyNames() // ["name", "awesome"] 

Limitaciones

  • Devuelve una matriz vacía para objetos Objective-C
  • No devolverá las propiedades calculadas, es decir:

     var favoriteFood: String { return "Lemon Cake" } 
  • Si self es una instancia de una clase (frente a, por ejemplo, una estructura), esto no informa las propiedades de su superclase, es decir:

     class Person : PropertyNames { var name = "Bruce Wayne" } class Superhero : Person { var hasSuperpowers = true } Superhero().propertyNames() // ["hasSuperpowers"] — no "name" 

    Podría solucionar esto utilizando superclassMirror() según su comportamiento deseado.

Usando class_copyPropertyList

Si está utilizando objetos Objective-C puede usar este enfoque:

 var count = UInt32() let classToInspect = NSURL.self let properties : UnsafeMutablePointer  = class_copyPropertyList(classToInspect, &count) var propertyNames = [String]() let intCount = Int(count) for var i = 0; i < intCount; i++ { let property : objc_property_t = properties[i] guard let propertyName = NSString(UTF8String: property_getName(property)) as? String else { debugPrint("Couldn't unwrap property name for \(property)") break } propertyNames.append(propertyName) } free(properties) print(propertyNames) 

La salida a la consola si classToInspect es NSURL :

["pathComponents", "lastPathComponent", "pathExtension", "URLByDeletingLastPathComponent", "URLByDeletingPathExtension", "URLByStandardizingPath", "URLByResolvingSymlinksInPath", "dataRepresentation", "absoluteString", "relativeString", "baseURL", "absoluteURL", "scheme", "resourceSpecifier", "host", "port", "user", "password", "path", "fragment", "parameterString", "query", "relativePath", "hasDirectoryPath", "fileSystemRepresentation", "fileURL", "standardizedURL", "filePathURL"]

Esto no funcionará en un patio de juegos. Simplemente reemplace NSURL con EachDayCell (o reutilice la misma lógica que una extensión) y debería funcionar.

Aquí hay otra versión. Creo que esto es muy simple y puro.

Swift 2.0

 protocol Reflectable { func properties()->[String] } extension Reflectable { func properties()->[String]{ var s = [String]() for c in Mirror(reflecting: self).children { if let name = c.label{ s.append(name) } } return s } } class Test:Reflectable { var name99:String = "" var name3:String = "" var name2:String = "" } Test().properties() 

Swift 1.2

 class Reflect:NSObject { func properties()->[String] { let m = reflect(self) var s = [String]() for i in 0.. 

Convertí el código de bolivia en Swift 4. Esta función toma un NSObject y devuelve un diccionario de las claves del objeto y el tipo de esa clave .

Tenga en cuenta que los tipos son feos. Para las propiedades primitivas, el motor devuelve un identificador de una letra (como B para bool, i para int, etc.) pero para los tipos Obj-C devuelve cosas como @"NSString" . Viendo que esto es solo una función de depuración para mí, no me importó. Si no quiere meterse con el diccionario, puede descomentar la línea de print y print a la consola. String(cString:cAttr) también contiene mucha información útil, incluso si la propiedad es mutable, es un estilo de referencia y mucho más. Para obtener más información sobre esto, aquí está la documentación de Apple.

 func getKeysAndTypes(forObject:Any?) -> Dictionary { var answer:Dictionary = [:] var counts = UInt32(); let properties = class_copyPropertyList(object_getClass(forObject), &counts); for i in 0.. 

Swift 3.1

 let contorller = UIActivityViewController(activityItems: [url], applicationActivities: nil) var count: UInt32 = 0 guard let properties = class_copyPropertyList(object_getClass(contorller), &count) else { return } for index in 0...count { let property1 = property_getName(properties[Int(index)]) let result1 = String(cString: property1!) print(result1) }