Question

If I use a core iOS class in my app, like NSURLCache; I would like to print a log message anytime [[NSURLCache sharedURLCache] removeAllCachedResponses] gets called. How can I extend a class method like that without explicitly subclassing NSURLCache and replacing all references of that within a project with a custom class? Is there some way to do this with category?

Was it helpful?

Solution

You can do it using Method Swizzling. Here is a page with a nice overview of the technique from which I borrowed most of the code below:

@interface SwizzleNSURLCache : NSURLCache
+(void)load;
-(void)swzl_removeAllCachedResponses;
@end

+(void)load {
    Class class = [SwizzleNSURLCache class];
    SEL originalSelector = @selector(removeAllCachedResponses);
    SEL swizzledSelector = @selector(swzl_removeAllCachedResponses);

    Method originalMethod = class_getInstanceMethod(class, originalSelector);
    Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);

    BOOL didAddMethod = class_addMethod(class,
        originalSelector,
        method_getImplementation(swizzledMethod),
        method_getTypeEncoding(swizzledMethod));

    if (didAddMethod) {
        class_replaceMethod(class,
            swizzledSelector,
            method_getImplementation(originalMethod),
            method_getTypeEncoding(originalMethod));
    } else {
        method_exchangeImplementations(originalMethod, swizzledMethod);
    }
}

-(void) swzl_removeAllCachedResponses {
    // This is your replacement method. You can do whatever you want here.
    NSLog(@"Running removeAllCachedResponses");
    // If you need to call the actual implementation, do it like this:
    [self swzl_removeAllCachedResponses];
}

You do not need to replace references of NSURLCache with this subclass. All you need is to load it once from some place in your program.

Note: I am not sure if there is an easier way to do it. Method swizzling is definitely a heavy artillery, but it gets the job done.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top