quicksilver/Quicksilver — Issue #621: Using proxy objects in actions
Author: skurfer
Created: 2011-12-15 14:39:16+00:00
State: open

In working on the iTunes module, I’ve run across something that might explain a lot of the inconsistent behavior we see with proxy objects. In essence, the proxy objects that represent tracks weren’t acting like tracks.

Doing something like this in an action fixes it:

if ([dObject respondsToSelector:@selector(proxyObject)]) {
dObject = [dObject proxyObject];
}

But surely we shouldn't require developers to repeat that step in every single action. Why don't we see problems with this more often? I've found at least two reasons.

1. The `QSProxyObject` class has it's own implementation of the `stringValue` method that will return the `stringValue` for the resolved object (whereas something like `displayName` will show the actual proxy name, like "Current Selection").
2. The `arrayForType` method calls `_safeObjectForType`, which detects and handles proxy objects

if (!object && [[self primaryType] isEqualToString:QSProxyType])
object = [[self resolvedObject] arrayForType:aKey];

Ideally, when writing actions, you should be able to treat all objects the same and not have to worry about whether or not it began its life as a proxy, right? Am I missing some use-case where a plug-in would need to know that it's being passed a proxy object?

I wanted to discuss possible solutions before making the changes.

We could modify `splitObjects` to understand and automatically resolve proxy objects before returning. That's probably the other most common way to deal with objects in actions (besides `stringValue` and `arrayForType`). But that still doesn't cover the case where a dev might use the object directly without attempting to split it (which I imagine is pretty common in existing plug-ins).

So maybe we should test for and resolve proxies before they're sent off to the actions. (In `QSInterfaceController.m: executeCommandThreaded` perhaps?) It seems like that would cover every case without requiring modification of existing plug-ins. Am I overlooking something?

FYI, I live by the mantra WW54D (What would B54 do?), so I tried some things with proxies and it exhibits the same problems.