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