I've recently come across the technique of swizzling. It looks like it's not a super common practice to use and I can understand the drawbacks I keep seeing listed for it. But as it's a thing that we can use in swift, I was hoping I could throw together something in a playground or practice project.
The idea I had was to use swizzling for analytics purposes. At this point, just to print off what the user is actually doing. I can't really think of interactions the user might make besides tapping buttons on their screen. I figure, I might be able to swizzle UITapGestureRecognizer
and make it run a function tracking tap position, etc. But that's too much information for me. I just want to know when a button is tapped. So I think the only thing I need to swizzle is the UIButton
. But we set the selector for UIButtons or we set them up as IBActions
.
So my question is, Is there a way to get a generic call to any button's method selector? That way, I can swizzle the button in one place. Make it run the analytics and then call the primary function all without actually changing my code in my UIViewController
classes directly.
I would post my attempts, but their rather sensical and I couldn't get anything to even run.
Is this a possibility?
You can try swizzling
sendAction(_:to:for:)
inUIControl
.UIControl
calls this whenever an event happens for every target-action pair.Caveats:
Since this method is called for every target-action pair, this means that this only works if all your buttons have exactly one target-action pair, and only for the event
touchUpInside
(a "tap"). In other words, for each button, you only calladdTarget
once, or add one connection in the storyboard fortouchUpInside
.If a button does not have any target-action pairs, then tapping it does nothing. The swizzled method will not be called.
If a button has multiple target-action pairs for
touchUpInside
, then tapping it would cause the swizzled method to be called multiple times.If a button has target-action pairs for events other than
touchUpInside
, then triggering those events would also cause the swizzled method to be called, though this can be prevented to an extent if you carefully check theUIEvent
parameter.To be honest, I would rather just subclass
UIButton
, instead of swizzling. Make a subclass that does something like this upon its creation: