View Debugging in Xcode 6

In this tutorial, you will learn view debugging by using some of the awesome new tools provided with Xcode 6! By Scott Berrevoets.

Leave a rating/review
Save for later
Share
You are currently viewing page 4 of 4 of this article. Click here to view the first page.

Old School Debugging

Live view debugging made debugging views in Xcode 6 a lot easier, but that doesn’t mean that your favorite old school tricks are now useless. In fact, iOS 8 introduces a very welcome addition to the family of view debugging tricks: _printHierarchy.

Note: You’ve already learned the basics of view debugging with Xcode 6, so feel free to skip this optional section if you’d like. However if you’re curious about some handy old-school techniques, read on!

Printing the View Controller Hierarchy

_printHierarchy is a private method on UIViewController that you can use to print the view controller hierarchy to the console. Build and Run, select Push via storyboard and then hit the pause button in the Debug bar.

Now type this in the console and press return:

po [[[[UIApplication sharedApplication] keyWindow] rootViewController] _printHierarchy]

You’ll get something very similar to this:

<UINavigationController 0x7fdf539216c0>, state: appeared, view: <UILayoutContainerView 0x7fdf51e33bc0>
   | <TableViewController 0x7fdf53921f10>, state: disappeared, view: <UITableView 0x7fdf5283fc00> not in the window
   | <DemoMessagesViewController 0x7fdf51d7d520>, state: appeared, view: <UIView 0x7fdf53c0b990>

This tells you that there is a UINavigationController whose first view controller is a TableViewController — the one where you chose how to push the controller. The second view controller is the DemoMessagesViewController, or the view controller you have been debugging.

It doesn’t seem too exciting in this particular example, but if you have several child view controllers within a navigation controller, and a tab bar controller in a popover in a modal view controller, (I’m not proud of some of my apps’ UI…) it can be immensely useful for figuring out exactly how the view controller hierarchy works.

Printing the View Hierarchy

If you’re not a very visual person and prefer a textual overview of a view hierarchy, you can always use the age-old, and also private, recursiveDescription on UIView. This prints a view hierarchy very similar to the view controller hierarchy as demonstrated above.

Open Views\JSQMessagesCollectionViewCellOutgoing.m and add a breakpoint in awakeFromNib.
breakpoint

Build and Run, then select Push via Storyboard. The debugger should break as a JSQMessagesCollectionViewCellOutgoing is loaded. Now type the following into the console:

po [self.contentView recursiveDescription]

This will print the hierarchy of the JSQMessagesCollectionViewCellOutgoing’s contentView, which will look something like this:

<UIView: 0x7fde6c475de0; frame = (0 0; 312 170); gestureRecognizers = <NSArray: 0x7fde6c484fe0>; layer = <CALayer: 0x7fde6c474750>>
   | <JSQMessagesLabel: 0x7fde6c475eb0; baseClass = UILabel; frame = (0 0; 312 20); text = 'Today 10:58 PM'; clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7fde6c476030>>
   | <JSQMessagesLabel: 0x7fde6c476400; baseClass = UILabel; frame = (0 20; 312 0); clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7fde6c476580>>
   | <UIView: 0x7fde6c476b50; frame = (70 20; 210 150); autoresize = RM+BM; layer = <CALayer: 0x7fde6c474dd0>>
   |    | <UIImageView: 0x7fde6c482880; frame = (0 0; 210 150); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x7fde6c476ae0>> - (null)
   | <UIView: 0x7fde6c482da0; frame = (282 140; 30 30); autoresize = RM+BM; layer = <CALayer: 0x7fde6c482d00>>
   |    | <UIImageView: 0x7fde6c482e70; frame = (0 0; 30 30); opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <CALayer: 0x7fde6c482f70>> - (null)
   | <JSQMessagesLabel: 0x7fde6c483390; baseClass = UILabel; frame = (0 170; 312 0); clipsToBounds = YES; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7fde6c483510>>

It’s rudimentary, but can be helpful when you want to debug a view hierarchy pre iOS 8.

Using debugQuickLookObject

Lastly, Xcode 5.1 introduced a feature called Debug Quick Look. This feature is most useful when you’re already debugging and aren’t wondering what an object looks like at a certain point in your code.

Your custom class can implement the method debugQuickLookObject and return anything that is visually presentable by Xcode. Then, when you’re debugging and you have an object you want to inspect, you can use quick look and Xcode will show you a visual representation of that object.

For example, NSURL’s implementation of debugQuickLookObject returns a UIWebView with that URL so you can actually see what’s behind the URL.

For more information on debugging using Quick Look, take a look at the documentation.

Where To Go From Here?

And that’s it for Live View Debugging. It’s an easy tool and can save hours of manually sifting through a view hierarchy trying to understand how and where it’s drawing views.

If you’re looking for a more advanced and comprehensive tool than just Xcode, then take a look at Reveal. While it’s a paid app, it’s also more powerful than Xcode’s view debugging. You can view our Tech Talk on the subject over here.

We hope you enjoyed this tutorial and feel a little more comfortable debugging your UI. If you have comments or questions, please use the forum discussion below!