commandsDict changes

Looking at this:

var commandsDict: [S : [StateCommand<E>]] = [:]

I can see a few problems with storing the StateCommand<E> objects in an array. The array could possibly hold multiple StateCommand<E> objects with the same event.
This shouldn’t be allowed. There should only be a single state to event relationship.

I could use nested dictionaries:

var commandsDict: [S : [E : StateCommand<E>]] = [:]

One alternative is to use a Set to store the StateCommand objects. The set will store an unordered, unique group of StateCommand objects.

var commandsDict: [S : Set<StateCommand<E>] = [:]

We can use generic typealiases for the Set:

typealias StateCommandSet<E> = Set<StateCommand<E>>

var commandsDict: [S : StateCommandSet<E>] = [:]

Objects that will be stored in a Set data structure must adopt the Hashable protocol. The StateCommand<E> class will need to adopt the Hashable protocol.

class StateCommand<E: Hashable> : Hashable {
    var event: E!
    
    var hashValue: Int {
          return event.hashValue
    }
    
    static func ==(lhs: StateCommand, rhs: StateCommand) -> Bool {
         return lhs.event == rhs.event
    }
}

The hashValue property returns the hash value of the event variable. In order to access the hash value of the event, we need to add a generic constraint to the class declaration to enforce that the generic type E conforms to the Hashable protocol. Now that StateCommand is compatible with the Set structure, we can add commands to the commandsDict object.

insert a command into the set:

var set: StateCommandSet<E> = StateCommandSet()
var command = StateCommand()
set.insert(command)

to retrieve items from a set use the filter() function:

let eventSet = set.filter { $0.event == .filter }

to get the item from the new set, get the first property:

if let command = eventSet.first {
    print(command.nextState)
    command.action()
}