Swift Diary #8: forwardInvocation

Let’s say I’m writing an image editor. (I use this example on my blog for historical reasons — because, historically, I like to rib Gus. It should not be taken as indicative.)

Here’s the problem I’m running into:

I have various layer classes (BitmapLayer, ShapeLayer, GroupLayer, etc.) that live outside the responder chain. There’s a Canvas object that is in the responder chain.

So I hook up my menu items and buttons with a nil target and whichever action makes sense.

Now, the Canvas object doesn’t implement the various actions that the layers implement. Instead, the Canvas object implements respondsToSelector: — it returns YES if the selected layer responds to that selector.

And then, if YES, forwardInvocation: in the Canvas object forwards the message to the selected layer.

Well, that’s the design, anyway. Sensible. Time-saving. Simple.

But forwardInvocation and NSInvocation are not available to Swift.

* * *

But, soft! What light through yonder window breaks!

While forwardInvocation: isn’t available, forwardingTargetForSelector: is available.

Which means the Canvas could see if the selected layer responds to that selector, and then does a performSelector: on that layer.


If so, then it means that anyone writing an image editor is good-to-go with Swift.

(That last sentence is the rib-Gus part again.)

* * *

However, Swift support for forwardInvocation: and NSInvocation would be useful. These things have their uses, and while forwardingTargetForSelector: can take care of some of them, they don’t take care of all of them.

* * *

Update 1:30 pm: Kyle Sluder reminds me:

Remember that -[NSResponder supplementalTargetForAction:…] does not require its return value to be an instance of UIResponder.

(Or NSResponder, in my case as a Mac app writer.)

At any rate, supplementalTarget​ForAction​:sender: might fill the bill even better. The Canvas object could return the selected layer object.

04 Aug 2015