I have a number of classes and inside class there are a number of methods defined. I need to perform a specific set of operations when each of these methods getting called. I can write the set of operations in each of the methods. But i don't want to mess up the code. So I have created a helper class, inside that I will pass the set of Classes and Selectors.
I have looped through the array and I used the swizzling technique and exchanged the implementation of each method with a custom method defined in the helper class. So whenever any of the method inside any of the above class triggered, I will get a call to my custom swizzling method.
But my problem is I am not able to distinguish which is the original method triggered. Based on that some of the parameter will change in the custom set of operations I mentioned above.
My current implementation is like the below:
for i in 0..<classes.count {
let eachClass:AnyClass = classes[i] as AnyClass
let eachSelector:Selector = selectors[i] as Selector
let swizzilableClass = MyHelper.self
let originalMethod = class_getInstanceMethod(eachClass, eachSelector)
let swizzledMethod = class_getInstanceMethod(swizzilableClass, #selector(MyHelper.trackMethodInvocation))
method_exchangeImplementations(originalMethod, swizzledMethod)
}
And the currensponding swizzled method is:
func trackMethodInvocation() -> Void {
}
So whenever any of the methods listed in the selectors array is called, the method trackMethodInvocation()
will trigger, but I need to know the original selector inside the trackMethodInvocation()
.
Is there any way to know which is the original method inside the swizzled method.
So somewhat I have found an alternative solution. Please note that * I will make sure the safety before going with live implementation. There won't be any more loops. What I will do is, I will swizzle the UIApplication's sendAction method with my custom method. And inside my custom method I will do my operations and will call the original sendAction method. So the code will now look like below,
let originalClass:AnyClass = UIApplication.self
let swizzilableClass = MyHelper.self
let originalMethod = class_getInstanceMethod(originalClass, #selector(UIApplication.sendAction(_:to:from:for:)))
let swizzledMethod = class_getInstanceMethod(swizzilableClass, #selector(MyHelper.trackMethodInvocation(_:to:from:for:)))
method_exchangeImplementations(originalMethod, swizzledMethod)
And my swizzled method will look like,
func trackMethodInvocation(_ action: Selector, to target: Any?, from sender: Any?, for event: UIEvent?) -> Void {
}
So here I will get the selector. So anyone who trying this, ***please make sure the safety in swizzling UIApplication method. Make sure to call the original method inside the swizzled method. Currently I am doing this for a research purpose only.