This article was written using Swift 4.2
I think that the single, most-used debugging tool many developers use is the print
statement. For many cases, the print
is enough for debugging common errors and for that, we most probably end up printing objects that we use in the code.
Sometimes, all we want is just a simple, pretty presentation of an object and all of its properties and values… and I got tired of writing a description
function for every object I want to print.
Through SO, I managed to somehow scrape a piece of code that can be written once in your project and you would be able to use it on any object to print a pretty representation of all its properties and their associated values.
How did I manage to do it, you ask? With the help of a protocol
, an extension
, and a protocol extension
. At first, I thought of extending Swift’s NSObject
to write a function that would be accessible to all classes inheriting from it, but then I remembered structs
. Swift’s structs
are a lightweight representation of classes that cannot inherit from anything, and a lot of today’s iOS apps and libraries rely on such structs
to represent their data and therefore I couldn’t just discard them.
Protocol + Extension: A true love story
We all know that a Protocol allows you to write some sort of contract specifying a bunch of properties and methods that any object conforming to this protocol should implement. We also know that an Extension allows you to extend any class or struct with more methods and computed properties even if that class is part of a third-party library that your project is using, for example, you can extend the Swift’sArray to offer convenience methods that you repeatedly use on your arrays.
But what some of you might not know is that you can write an extension on a protocol to provide a concrete implementation of some or all methods defined in a protocol. As a result, any object conforming to that protocol does not have to implement these concrete methods and will have that implementation by default! Pretty sweet. This means that I can write a protocol say, Presentable that defines a read-only property called dictionaryPresentation
, and then write an extension on that protocol that implements the getter for this property and boom, any objects, class or struct, that conforms to Presentable will have this dictionaryRepresentation
automatically.
This looks fine but it’s not enough to be printed in a pretty way. And as I said, we’re going to use a protocol, an extension, and a protocol extension and we’ve only the first and last ones. So let’s go ahead and create an extension
on the Dictionary
class to print its contents in a presentable way.
And we’re basically done! Go ahead and try this out in any project of yours. For example, if you have a Person struct
, set it to conform to Presentable
and then call something like print(Person().dictionary.pretty)
.
Top comments (0)