You've already figured it out. Swift protocols don't map as types into Objective-C.
Always just ask yourself "Could I say this in Objective-C?" You can't say this in Objective-C:
+ (void) sayValue: (Printable*) value { ... }
That's illegal, because Printable (a protocol) isn't a type. So your Swift function defined that way doesn't magically map upward into Objective-C, as it has nothing to map to. It is filtered out, and Objective-C never sees it.
What I'm finding is that all this works remarkably cleanly. I was afraid that a Swift class that uses any non-Objective-C features wouldn't map to an Objective-C class at all. But, on the contrary, you can use all the pure-Swift features you like, and they simply don't map up into Objective-C: they are cleanly filtered out, and those parts of your Swift class that do map into Objective-C work just fine from Objective-C. It's quite brilliant.
You are free to define a protocol that maps as a type for purposes of, say, defining a delegate. But to do that, you must expose the protocol using @objc. For example, from one of my apps:
@objc protocol ColorPickerDelegate {
func colorPicker (/*...*/)
}
class ColorPickerController : UIViewController {
weak var delegate: ColorPickerDelegate?
// ...
}
You can't talk that way unless the protocol is @objc. Now Objective-C understands the type of delegate to mean id<ColorPickerDelegate> and you're in business.
(So you could probably talk the way you're suggesting by defining an @objc protocol MyPrintable which does nothing but adopt Printable; I haven't tried it, however, so that's just a conjecture.)