Have you ever noticed how useless Swift’s class representations are? Value types automatically show their members and values but classes don’t. What if you could add a simple way to automatically reflect those members, like with C2
?
Mike Ash threw together an adorable solution that introduces a default reflection for any conforming class:
/// A reference type that provides a better default representation than the class name public protocol DefaultReflectable: CustomStringConvertible {} /// A default implementation that enables class members to display their values extension DefaultReflectable { /// Constructs a better representation using reflection internal func DefaultDescription<T>(instance: T) -> String { let mirror = Mirror(reflecting: instance) let chunks = mirror.children.map({ (label: String?, value: Any) -> String in if let label = label { if value is String { return "\(label): \"\(value)\"" } return "\(label): \(value)" } else { return "\(value)" } }) if chunks.count > 0 { let chunksString = chunks.joinWithSeparator(", ") return "\(mirror.subjectType)(\(chunksString))" } else { return "\(instance)" } } /// Conforms to CustomStringConvertible public var description: String { return DefaultDescription(self) } }
Unfortunately, you cannot (at least at this time) conform AnyObject
and get this for free (“error: ‘AnyObject’ protocol cannot be extended”).
Manuel Carlos offers this:
3 Comments
Using `Streamable` instead of `CustomStringConvertible` can be apply to `AnyObject`. https://gist.github.com/norio-nomura/e1e0cff0fc7c3c80f65d5af7c56450e1
The class Mirror is like a good joke. First It’s not natural to use it. It’s not a swifty class. And second we can dynamically get value of properties but not set dynamically a value to a property. Because the reflection in swift is not good many frameworks try to mimic a reflection behaviour with layers of generic classes.
This falls over dead if you have a circular reference (such as a delegate) pointing back to a parent object.