Method swizzling not woking in Cocoa pod

225 Views Asked by At

I'm developing a pod which should use method swizzling at some point and I have a problem to call swizzled method when calling original one. I checked my swizzling in the simple POC (to be sure my swizzling is ok) and it works perfectly fine, but as cocoa pod (with mark use_framework in pod file even) it doesn't work, so I was debugging it and method exchange happens, it finds original method and swizzled method implementations, etc. but swizzled method doesn't get called which should happen in the main app, that has my pod. method swizzling is written using objective-c Anyone had such problems? Code from my POC

Swizzler

- (BOOL)swizzleClass:(Class)class
replaceInstanceMethod:(SEL)methodSelector1
          withMethod:(SEL)methodSelector2 {
    
    if (!class || !methodSelector1 || !methodSelector2) {
        NSLog(@"Nil Parameter(s) found when swizzling.");
        return NO;
    }
    
    Method method1 = class_getInstanceMethod(class, methodSelector1);
    Method method2 = class_getInstanceMethod(class, methodSelector2);
    
    if (method1 && method2) {
        method_exchangeImplementations(method1, method2);
        return YES;
        
    } else {
        NSLog(@"Swizzling Method(s) not found while swizzling class %@.", NSStringFromClass(class));
        return NO;
    }
}

Class category

+ (void)load {
    static dispatch_once_t once_token;
    dispatch_once(&once_token,  ^{
        
        swizzler = [[Swizzler alloc] init];
         
         swizzleSuccess = [swizzler swizzleClass:self replaceInstanceMethod:@selector(wristLocation) withMethod: @selector(swizzled_wristLocation)];
         
         if (swizzleSuccess) {
             NSLog(@"Successss  swizzle");
         } else {
             NSLog(@"Cannot swizzle");
         }
        
    });
}

- (void)setLocation:(WKInterfaceDeviceWristLocation)location {
    testWristLocation =  [[NSNumber alloc] initWithInt: location];
}

- (WKInterfaceDeviceWristLocation)swizzled_wristLocation {
    NSLog(@"Called swizzled method .");
    [self swizzled_wristLocation];
    return [testWristLocation intValue];
}

Class where I call it

@IBOutlet weak var locationLabel: WKInterfaceLabel!
    
    override func awake(withContext context: Any?) {
        
        WKInterfaceDevice.current().setLocation(WKInterfaceDeviceWristLocation.right)
        
        updateLocation()
    }
    
    @IBAction func checkLocation() {
        updateLocation()
    }
    
    dynamic private func updateLocation() {
        let location = WKInterfaceDevice.current().wristLocation
        switch location {
        case .left:
            self.locationLabel.setText("left")
        case .right:
            self.locationLabel.setText("right")
        @unknown default:
            self.locationLabel.setText("unknown")
        }
    }
1

There are 1 best solutions below

1
zhanch On

So, I find out what was wrong here. The problem was in wrong target membership, I was swizzling in one target and expecting swizzled method to be called in another (which is basically another app). Right code sharing fixed the problem.