1
First of all, you create the ErrorPopoverRenderer protocol with a plan for the presentError(...) method. Then you extend the UIViewController class to conform to this protocol, implementing the (required) plan for the presentError(...) method.
This means that you can subclass UIViewController) with the additional protocol restriction ErrorPopoverRenderer for the subclass. If the UIViewController not been extended to comply with the ErrorPopoverRenderer protocol, the following code in your example will result in a compile-time error ( ... does not comply to protocol ErrorPopoverRenderer )
class KrakenViewController: UIViewController, ErrorPopoverRenderer { func failedToEatHuman() {
However, there is a possible problem with this method, as shown in your link:
Now we must implement each parameter every time we want to present an ErrorView. Such a crap, because we can not value for the declarations of protocol functions.
Thus, the ErrorPopoverRenderer protocol ErrorPopoverRenderer not intended solely for the use of UIViewController : s (or its subclasses), then the above solution is not very general.
2
If we want to use ErrorPopoverRenderer more widely, we will place specific drawings for each type of class that could use the protocol in protocol extensions. This is very neat, since the more specific parts of the ErrorPopoverRenderer drawings for the presentError() method can be set differently for different classes that may correspond to the protocol, and the presentError() method can be made more minimalistic.
I quote for example:
Using Self here means that this extension will only ever take place if and only if the converter inherits from the UIViewController. This gives us the opportunity to assume that ErrorPopoverRenderer is indeed a UIViewController without even extending the UIViewController.
In this method, since the code now knows (we already, in 1.) that it is a view controller that will call presentError() , we can place the specific UIViewController material directly in the implementation of the drawing, and we donβt need to send it as a long list arguments.
Therefore, 2. for this specific use, it is a kind of more βgeneralβ approach in the sense that we slightly minimize code duplication (calling presentError() vs presentError(... lots of args ...) from several different UIViewController : s )