adamweeks adamweeks - 1 year ago 63
Objective-C Question

Logging the class name of all UIViewControllers in a project

We have received a HUGE project from outsourcing that we are trying to "repair". There are hundreds of view controllers within the project. Our goal is to easily determine which class we are currently looking at on the device.

Our solution (which didn't work, hence the SO question) follows.

Override the viewDidAppear method of UIViewController via a category with this:

NSLog(@"Current View Class: %@", NSStringFromClass(self.class));
[self viewDidAppear:animated];
//Also tried this:
//[super viewDidAppear:animated];

This category would be put in the .pch of the project.

This would require no extra code to be put in the hundreds of View Controllers and be easily turned on and off. It didn't work because, as we've learned now, <meme>one does not simply override an existing method via category</meme>.

What are we missing?!?

Answer Source

The answer is to swizzle the methods! Here is what we came up with:

#import "UIViewController+Logging.h"
#import <objc/runtime.h>

@implementation UIViewController (Logging)

    NSLog(@"Current View Class: %@", NSStringFromClass(self.class));
    [self swizzled_viewDidAppear:animated];

+ (void)load
    Method original, swizzled;

    original = class_getInstanceMethod(self, @selector(viewDidAppear:));
    swizzled = class_getInstanceMethod(self, @selector(swizzled_viewDidAppear:));

    method_exchangeImplementations(original, swizzled);