Weird way to retrieve object passed through NotificationCenter

I am using NotificationCenter to send and catch an "event" with a "sender" and another parameter.

The type I am sending is declared as:

class Command<S, I, E> : CommandProtocol, PermissibleCommand
{

CommandProtocol contains three associated types, which are fulfilled by the generic parameters S, I and E; PermissibleCommand is a non-ATS protocol.

An instance of Command<S, I, E> is passed to the NotificationCenter, along with a parameter thus:

NotificationCenter.default.post(name: .notificationName, object: command, userInfo: ["args" : args])

Now, the object parameter is of type Any?.

At the "receiving end", is a wrapper around NotificationCenter, which contains this closure:

  public static func handle<senderT, argsT : EventArgs>(name: Notification.Name,
                                                        sender: senderT,
                                                        closure: Event<senderT, argsT>.Closure) -> AnyObject
  {
    return NotificationCenter.default.addObserver(forName: name, object: sender, queue: nil)
    {
      notification in
      
      guard let sender = notification.object as? senderT,
            let args = notification.userInfo?["args"] as? argsT else
      {
        return
      }
      
      closure.invoke(sender: sender, args: args)
    }
  }

senderT is actually equivalent to Any

The closure that gets invoked at the end ends up looking like this:

  public lazy var changeClosure: ChangeClosure = .init
  {
    sender, args in
    
    DispatchQueue.main.async
    {
      guard let control = self.control,
            let permissibleCommand = (sender as Any?).flattened as? PermissibleCommand else
      {
        return
      }
      
      control.isEnabled = permissibleCommand.isEnabled
    }
  }

I am extending Optional with the Flattenable protocol as described by Nevin here.

If I just do this:

      guard let control = self.control,
            let permissibleCommand = sender as? PermissibleCommand else
      {
        return
      }

… the cast always fails.

I know that the sender parameter here is of type Any but it actually contains an Optional<Command<S, I, E>.

I realise that getting anything that might be an Optional out of an Any is not straight forward, but I just wanted to check whether what I am doing is not "excessive" or that I am missing a simpler way of getting from an Any to a non-ATS protocol.

Call it a sanity check :sunglasses:

Terms of Service

Privacy Policy

Cookie Policy