2

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")
        }
    }
zhanch
  • 145
  • 1
  • 8
  • 2
    Please always post your code when asking such questions so that we can debug what it is you have done – Simon McLoughlin Jan 17 '22 at 14:08
  • @SimonMcLoughlin The same code works in POC Only one difference that - Swizzler code and Category code happens in pod and called from the app – zhanch Jan 17 '22 at 14:38

1 Answers1

0

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.

zhanch
  • 145
  • 1
  • 8
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Feb 02 '22 at 17:00