TL DR → scroll down
When trying to bind Apple to protocol-oriented programming using Swift, I came across the following problem, trying to implement a delegation pattern between classes.
I will start with this example:
protocol PhotoHandlerParent {} class UIViewController {} class MyViewController: UIViewController, PhotoHandlerParent {} class PhotoHandler: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate { weak var delegate: PhotoHandlerParent }
So far so good. The MyViewController instance will be happily assigned as the PhotoHandler delegate. But I will say that I not only wanted the delegate object to match PhotoHandlerParent , but also had a UIViewController class. In this particular example, so that PhotoHandler can submit and reject the UIImagePickerController on behalf of its parent view controller. Is very similar:
protocol PhotoHandlerParent {} class UIViewController {} class MyViewController: UIViewController, PhotoHandlerParent {} class PhotoHandler: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate { weak var delegate: UIViewController, PhotoHandlerParent }
Unfortunately, the above code does not work on Swift. On the other hand, although Swift has Generics, this may help in this case. So you can try:
protocol PhotoHandlerParent {} class UIViewController {} class MyViewController: UIViewController, PhotoHandlerParent {} class PhotoHandler<Parent where Parent: UIViewController, Parent: PhotoHandlerParent>: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate { weak var delegate: Parent }
Now, interestingly, the MyViewController instance will return to a happy appointment as a PhotoHandler delegate. Compilation error, no runtime error. But...
TL DR: problem
By running the sample code for this question, you can see that an instance of a class declared using Generics and set as a UIImagePickerController delegate is never called by this. An instance of a declared object without is generated using the UIImagePickerController .
My best guess is that the compiler is not complaining because it can make sure that PhotoHandler matches UIImagePickerControllerDelegate . However, at run time, the instance of PhotoHandler is actually an instance of PhotoHandler<MyViewController> , so it somehow prevents the UIImagePickerController identifying that its delegate is actually implementing its protocol.
Or am I missing something?
Greetings