Is it possible to intercept all method class on any UIViewController subclass

284 Views Asked by At

Let's say I wanted to be able to intercept any method calls to a UIViewController subclass.

First of all, I swizzle the +(instancetype)alloc method and I check if the current instance isKindOfClass:[UIViewController class]. If it is I go ahead and instantiate my proxy with the target.

///swizzled Alloc
+ (instancetype)monitoredAlloc {
     id obj = [self monitoredAlloc];
     if([obj isKindOfClass:[UIViewController class]]) {
        id proxy = [PMGProxy proxyWithObject:obj];
        return proxy;
     }
    return [self monitoredAlloc];
}
 ---------------------------------------
/// Proxy class
@implementation PMGProxy

+ (instancetype)proxyWithObject:(id)obj {
    PMGProxy *proxy = [self alloc];
    proxy.obj = obj;
    return proxy;
}


- (void)forwardInvocation:(NSInvocation *)invocation
{
    [invocation setTarget:_obj];
    [invocation invoke];
}

-(NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
    return [self.obj methodSignatureForSelector:sel];
}

- (Class)class {
    return [self.obj class];
}

The problem is that I get crashes, so I would expect the implementation of my Proxy is wrong... What am I doing wrong?

Here is the exception:

*** Terminating app due to uncaught exception 'NSGenericException', reason: 'This coder requires that replaced objects be returned from initWithCoder:'
1

There are 1 best solutions below

0
On

From the error it seems that the coder is only happy to accept a different class returned from initCoder: rather than earlier in the process at the alloc stage.

Might be worth looking up NSSecureCoding for more detail on the whole process.

While you’re at it, take a look at the stack track that resulted in your exception, it will give you a bit more perspective on just how deep this rabbit hole goes.