Is there a Simple way in Swift to iterate over the attributes of a class.
i.e. i have a class Person, and it has 3 attributes: name, lastname, age.
is there
They have removed reflect within Swift 2.0. This is how I am enumerating attributes and values.
class People {
var name = ""
var last_name = ""
var age = 0
}
var user = People()
user.name = "user name"
user.last_name = "user lastname"
user.age = 20
let mirrored_object = Mirror(reflecting: user)
// Swift 2
for (index, attr) in mirrored_object.children.enumerate() {
if let property_name = attr.label as String! {
print("Attr \(index): \(property_name) = \(attr.value)")
}
}
// Swift 3 and after
for (index, attr) in mirrored_object.children.enumerated() {
if let property_name = attr.label as String! {
print("Attr \(index): \(property_name) = \(attr.value)")
}
}
Output:
Attr 0: name = user name
Attr 1: last_name = user lastname
Attr 2: age = 20
Here's Swift 5
version of object description:
class TestClass: CustomStringConvertible {
public var description: String {
return Mirror(reflecting: self).children.compactMap({
if let label = $0.label {
return "\(label): \($0.value)"
}
return ""
}).joined(separator: "\n")
}
}
Yes, if you just need to print properties of a struct or class, and the properties are simple types like String and Int, you can use reflect
and MirrorType
.
func print_properties(mirror: MirrorType) {
for i in 0..<mirror.count {
let (name, childMirror) = mirror[i]
let value = childMirror.value
println("\(i): \(name) = \(value)")
}
}
struct Person {
let first_name: String
let last_name: String
let age: Int
}
let john = Person(first_name:"John", last_name:"Doe", age:27)
let mirror = reflect(john)
print_properties(mirror)
If you have nested structs, enums, you need to do a bit more work.
As @mohacs suggested, You can provide a function Description in your required class like follows;
func description() -> String{
let mirrored_object = Mirror(reflecting: self)
let str:NSMutableString = NSMutableString()
for (index, attr) in mirrored_object.children.enumerated() {
if let property_name = attr.label as String! {
str.append(" Attr \(index): \(property_name) = \(attr.value)")
}
}
//print("desc=\(str)")
return str as String
}
Then simple call this instance method
let jsonOb:JsonModel = self.ObjArray[Index]
print("jsonOb = \(jsonOb.description())")
Apple didn't remove reflect
,they just change it to _reflect
,they also changed MirrorType
to _MirrorType
.
The Swift 2.0 version of @Teemu Kurppa 's code:
func print_properties(mirror: _MirrorType) {
for i in 0..<mirror.count {
let (name, childMirror) = mirror[i]
let value = childMirror.value
print("\(i): \(name) = \(value) ")
}
}
struct Person {
let first_name: String
let last_name: String
let age: Int
}
let john = Person(first_name:"John", last_name:"Doe", age:27)
let mirror = _reflect(john)
print_properties(mirror)