0

I have a custom delegate that triggers certain events. For context, it's a bluetooth device that fires events arbitrarily. I'd like my view controllers to optionally subscribe to these events that get triggered by the device delegate.

It doesn't make sense that each view controller conforms to the custom delegate because that means the device variable would be local and would only fire in that view controller. Other view controllers wouldn't be aware of the change. Another concrete example would be CLLocationManagerDelegate - for example what if I wanted all view controllers to listen to the GPS coordinate changes?

Instead, I was thinking more of a global delegate that all view controllers can subscribe to. So if one view controller triggers a request, the device would call the delegate function for all subscribed view controllers that are listening.

How can I achieve this architectural design? Are delegates not the right approach? I thought maybe NotificationCenter can help here, but seems too loosely typed, perhaps throwing protocols would help makes things more manageable/elegant? Any help would be greatly appreciated!

TruMan1
  • 33,665
  • 59
  • 184
  • 335

2 Answers2

1

You could have an array of subscribers that would get notified.

class CustomNotifier {

    private var targets : [AnyObject] = [AnyObject]()
    private var actions : [Selector]  = [Selector]()


    func addGlobalEventTarget(target: AnyObject, action: Selector) {

        targets.append(target)
        actions.append(action)
    }

    private func notifyEveryone () {

        for index in 0 ..< targets.count {

            if targets[index].respondsToSelector(actions[index]) {

                targets[index].performSelector(actions[index])
            }
        }
    }
}

Naturally, you'd have to plan further to maintain the lifecycle of targets and actions, and provide a way to unsubscribe etc.

Note: Also ideal would be for the array of targets and actions to be an of weak objects. This SO question, for instance, deals with the subject.

Community
  • 1
  • 1
Vinod Vishwanath
  • 5,821
  • 2
  • 26
  • 40
0

NotificationCenter is first solution that comes in mind. Yes, it is loosely typed. But you can improve it. For example like this:

extension NSNotificationCenter {

    private let myCustomNotification = "MyCustomNotification"

    func postMyCustomNotification() {
        postNotification(myCustomNotification)
    }

    func addMyCustomNotificationObserverUsingBlock(block: () -> ()) -> NSObjectProtocol {
        return addObserverForName(myCustomNotification, object: nil, queue: nil) { _ in
            block()
        }
    }

}

• Second solution would be to create some shared object, which will store all delegates or blocks/closures and will trigger them when needed. Such object basically will be the same as using NotificationCenter, but gives you more control.

Silmaril
  • 4,241
  • 20
  • 22