square/PonyDebugger — pull request #22 by ryanolsonk (2012-09-29 02:29:13+00:00)
Title: Add View Hierarchy Debugging in the Elements Tab

First, thanks so much for building this tool and making it open! It's quickly becoming a key part of my iOS development workflow. The network debugging and core data browsing are probably the most useful pieces, but looking at the empty elements tab left me wanting a little more. I saw a HN comment from Mike saying that populating the elements tab would be reasonably straightforward, so I started digging in and got to work. It's awesome that you guys built this to support the whole inspector protocol. I was impressed by how easy it was to plug in new functionality.

So, getting to it, this pull request adds view hierarchy debugging to PonyDebugger through a new PDDomainController subclass (PDDOMDomainController) which implements part of the PDDOMCommandDelegate protocol.

Windows and views are displayed in an XML tree in the elements tab. Certain properties of each view are displayed as attributes of the nodes. Users can change which properties to display by passing an array of UIView key paths to PDDebugger's `- (void)setDisplayedViewAttributeKeyPaths:(NSArray *)keyPaths;` The properties can be live-edited straight from the elements panel, though at the moment only CGPoint, CGSize, CGRect, and numeric types (including BOOL) are supported.

As nodes are selected in the elements tab, the corresponding view is highlighted in the iOS application. The position and sizing of the selected view can be changed by dragging and pinching. Pressing delete with a view selected will remove it from the hierarchy.

The PDDOMDomainController sequentially generates nodes with increasing nodeIds by traversing the entire view hierarchy when it receives the `domain:getDocumentWithCallback:` call. The mappings between nodeIds and view objects are maintained by mirrored dictionaries to provide fast lookup in both directions. Changes to the view hierarchy are monitored by swizzling all of the UIView add/remove/insert/etc. methods to inject code to update the corresponding nodes. Each node's attributes are kept up to date by using KVO on all of the displayed properties. The highlight overlay also uses KVO to track the frame of the view it is supposed to be highlighting.

I'm happy to go into more details, but I think this should give you a good high level view of what's going on. There's definitely more to be done in the elements panel, but I think this provides a good starting point. I'd love to hear feedback/complaints/whatever!

![Pony!!!](https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcRMNe08uD98Lsbrs2blI4xfVsSe0bCuhHkLNQhXHET2rMAAbnuDNg)