Why not just use protocols (never using extensions) or why not just use extensions (never using protocols)?
Protocols serve as a "blueprint" for a struct, class, or enum—they define a set of required properties and methods, as well as any other protocols that must be conformed to. In other words, they are for requiring functionality.
Extensions offer a way to add extra computed properties and methods to an existing struct, class, enum, or to a protocol. In other words, they are for extending functionality.
Because they serve different purposes, they are not either/or concepts. But they can be used together to bring extended functionality to a whole group of structs or classes at once.
Here's a concrete example where I used this recently. I want to be able to take anything that can be encoded as Data, and be able to encrypt it, transmit the encrypted form as Data, then unencrypt it, and decode the unencrypted Data back into an object. Now, I could write an encrypt function for each and every