#02: CustomStringConvertible and Description in Swift

In Swift you can provide a custom string description of your objects implementing the CustomStringConvertible protocol and adding a new computed property called description:


class AClass {
    var prop = "Hey!"
}

extension AClass: CustomStringConvertible {
    var description: String {
        return prop
    }
}

let c = AClass()
print(c)  // "Hey!"

This serves the same purpose of the description method of NSObject we were used to override in Objective-C.

Debugging description

Swift also provide a CustomDebugStringConvertible protocol that should provide an additional, usually more detailed, description of your objects, for debugging purposes.


class AClass {
    var prop = "Hey!"
}

extension AClass: CustomDebugStringConvertible {
    var debugDescription: String {
        return prop
    }
}

let c = AClass()
debugPrint(c)  // "Hey!"

This kind of description is printed by a specific method, debugPrint.

Most of the times, implementing only one method will suffice but for more complex objects, that could need different views of the content during debugging, providing more than one representation could make sense.

Removing print and debugPrint from release builds

There are different ways to remove the print instructions we added to our code only for debugging and that we don’t need anymore in release builds.

The most common one consists in checking the DEBUG flag:


#if DEBUG
    printDebug(object)
#endif

This will completely remove print statements (and the static strings you were using for the messages) from the release binary reducing its size (a nice perk).

But surrounding every print instruction with this check could add too much visual clutter if you use this debugging method extensively in your code.

This is why, in some cases, we could choose one of these alternative approaches:

  • Implementing a Logger class that manages logging and disables prints when compiled for release
  • Override the print methods to stop printing when in release

Let’s seen how we can easily implement the second alternative including just a few new lines in our application:


#if !DEBUG
func print(_: Any..., separator: String, terminator: String){}
func debugPrint(_: Any..., separator: String, terminator: String){}
#endif

That’s it, this override will prevent the print methods from producing any output.

Did you like this article? Let me know on Twitter or subscribe for updates!


I'm also on Twitter and GitHub.

Subscribe via RSS or email.