Trailing where clause for extension of non-generic type
The solution was simple to switch the order in the extension clause:
extension UIViewController where Self: KeyboardNotificationDelegate
should be
extension KeyboardNotificationDelegate where Self: UIViewController
extension Foo where ...
can only be used if Foo
is
- a generic class or structure: extend with a default implementation for generics conforming to some type constraint,
- a protocol containing some associated types, extend with a default implementation for when an associated type conform to some type constraint
- a protocol where we extend with a default implementation for when
Self
is of a specific (object/reference) type, or conforms to some type constraint.
E.g.
// 1class Foo<T> { }extension Foo where T: IntegerType {}struct Foz<T> {}extension Foz where T: IntegerType {}// 2protocol Bar { associatedtype T}extension Bar where T: IntegerType {}// 3protocol Baz {}extension Baz where Self: IntegerType {}class Bax<T>: Baz {}extension Baz where Self: Bax<Int> { func foo() { print("foo") }}let a = Bax<Int>()a.foo() // foo
In your case, UIViewController
is a non-generic class type, which does not conform to any of the two above.
As you've written in your own answer, the solution is to extend your delegate protocol with a default implementation for cases where Self: UIViewController
, rather than attempting to extend UIViewController
.