Lost in a piece of code that you can’t seem to debug? Xcode’s debugger being a tad bit ambiguous? Try using the .debugDescription method from the CustomDebugStringConvertible protocol in conforming types.
Signal the flashback…
Last night, as I was trying to get the AVFoundation framework to work in my app, I came across a weird bug that I couldn’t quite figure out. If you have experience with Swift, you might not be surprised to find out that it was ultimately due to an optional, specifically due to an AVCaptureSession method. Long story short, I was messing around with this particular error for nearly an hour before I found a shiny gold nugget in the form of the .debugDescription instance property.
Classes that conform to the CustomDebugStringConvertible protocol (and believe me, there’s quite a few) all have this instance property, and using it will make your life so much better! Here’s why:
Now, this might not look like much, until you see what the output looks like when captureSession isn’t initialized.
Obvious! Right? I’ll admit that when I first realized what a bonehead I was for not setting up my capture session correctly, I felt kinda stupid. It’s one of those obvious errors that you should be able to pick-up without thinking twice about it. Debugging is an inherently tricky thing to do. No matter how many times you skim through your code, set strategic breakpoints, or ask your programmer friends for help, there are bound to be bugs that are ever elusive and increasingly frustrating.
Queue the print statements.
In my CS education, I’ve heard many people preach about one debugging paradigm over another. Flame wars have been waged over which IDE has the best built in debugger, and keyboard jockeys tout the benefits of GDB in the terminal. No matter your views on debugging paradigms (oh the joy!), you will one day have to admit that the good ole’ print statement is a valuable tool in any strategy. By using the standard output to print messages to the terminal, you’re customizing your debug experience to a level that the compiler and your fancy debugger can’t quite match.
Take this bit of code for example:
Here, we have a default view nested within a standard ViewController. Since view.layer.sublayers! returns an array of the views’ current layers, I can retrieve information about the layers that make up my view. I use a for loop to iterate through the debug description for each layer. The results:
That’s a lot of information!
Let’s see what we got here
- Custom debug tags (SUBLAYER: can be changed to anything you find helpful)
- Class name and (some hex value, possibly memaddr??)
- Position, bounds, origin, height, width
- Delegate status and specifications
- Layer properties
- Color profiles
That’s a lot of valuable information, and it can be realized with code that can fit in a single line. It’s hard to find a solution that has the potential to be so elegant with minimal work and setup cost. The beauty of it is that many of the fundamental types of Swift conform to this protocol, and can provide you with loads of information that you would otherwise have to dig through your debugger for. I’ve yet to really dig into the true utility of .debugDescription, but I’m looking forward to using it as a tool in my coming iOS development career.
Now, to you, my dear reader. If you happen to have an XCode debug tip and/or trick, leave me a comment below. As I said, I’m still quite new to this, and I’m always happy to pick your brain and share your thoughts 😉