Forward selector to multiple objects in Swift

Viewed 510

I'm trying to re-implement a class in Swift, but have run into problems. My pattern is to have a single object which forwards methods in a protocol to multiple other objects.

I have a protocol which looks like:

@protocol AnalyticsProvider {
@optional

    - (void)showHomePage;
    - (void)selectedMenuItem:(NSString *)item;

    // ...
    // 100 or so more methods :sigh:
    // ...

@end

The idea being that I can call showHomePage on a singleton and have it forwarded to multiple objects who will each do their own thing with that message.

I would configure the singleton on startup like this:

[AppAnalytics sharedAnalytics] setProviders:@[ myFlurryProvider, myOmnitureProvider] ];

where myFlurryProvider and myOmnitureProvider are real implementers of the AnalyticsProvider protocol. And then in my view controllers I would have lines like this:

[[AppAnalytics sharedAnalytics] showHomePage];

This should send homepage analytics events to both Flurry and Adobe Omniture, for example. This works because the AppAnalytics class implements the AnalyticsProvider protocol but doesn't actually contain code for any of the methods.

By implementing forwardInvocation: in AppAnalytics I can forward the methods to each provider i.e.

- (void)forwardImplementation:(NSInvocation *invocation) {
    for provider in providers
        if ([provider respondsToSelector:invocation.selector])
            [invocation performWithTarget:provider]
}

By not implementing any of the methods in my AppAnalytics singleton the calls are automagically passed into forwardImplementation: as an NSInvocation, but because AppAnalytics conforms to the protocol I get compiler safety at the point of calling. win win. It's fairly important I don't have to actually implement any methods in AppAnalytics because there are 100s of them and I don't want that much repeated code!

Any ideas on a good way to implement this in Swift, given that NSInvocation is forbidden!

1 Answers
Related