Disagree somewhat with your definition of a protocol, none of which really discuss behavior.
While one can indeed abstract dependencies as protocols, in Swift a protocol is largely an expression of behavior.
Coddable, Equatable, Hashable, Sequence, Collection.... all basically tell how an instance of something will behave, or they tell you about the interfaces or functionality that object can support.
Also a minor quibble with your suggestion of switch in ProductType. You mention that you wouldn't use it for types where you have a lot of cases, but one probably also shouldn't use it if you have a few cases but a lot of associated functionality.
If have more than one or two functions each switching on self, then you should probably punt back to a protocol where you can implement polymorphic behaviors.
That said, the Stop Using Protocols article is indeed a mess, with simplifications that are anything but.