How to declare Swift protocol for a specific class

⋅ 2 min read ⋅ Swift Protocol

Table of Contents

A protocol defines a blueprint of methods, properties, and other requirements. The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of those requirements.

But there would be a time when you want to restrict protocols to be adopted by a specific class. In Swift 5, you can do just that.

Syntax

You have two ways to declare this.

protocol MyViewController: UIViewController { /*...*/ }

protocol MyViewController where Self: UIViewController { /*...*/ }

This syntax makes a protocol constrain their conforming types to a subclass (or is a type) of UIViewController.

You can easily support sarunw.com by checking out this sponsor.

Sponsor sarunw.com and reach thousands of iOS developers.

Error

If you try to adopt this protocol from non UIViewController subclass, you will get an error.

class Foo: MyViewController {}
// 'MyViewController' requires that 'Foo' inherit from 'UIViewController'

Benefits

Declare your protocol like this is semantically equivalent to a class existential of UIViewController & MyViewController. That's mean you can access both members of the class and requirements of the protocol.

protocol MyViewController: UIViewController {
func foo()
}

class Example: UIViewController {
var myViewController: MyViewController?

override func viewDidLoad() {
super.viewDidLoad()

myViewController?.foo()
myViewController?.title = "Foo"
}
}

In the above example, you can access a view controller title and foo() method from the MyViewController protocol.

Extension

You can also use this syntax with a protocol extension. Which will add default Implementations just for the specified class.

protocol P {
func foo()
}
extension P where Self: UIViewController {
func foo() {
print("You can reference UIViewController property here: \(view)")
}
}

The above example will add a default implementation of foo() for any subclass of UIViewController that conform to P protocol.

// No error
class ViewController: UIViewController, P {

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
foo()
}
}

// Type 'Struct' does not conform to protocol 'P'
struct Struct: P {}

You can easily support sarunw.com by checking out this sponsor.

Sponsor sarunw.com and reach thousands of iOS developers.

Read more article about Swift, Protocol, or see all available topic

Enjoy the read?

If you enjoy this article, you can subscribe to the weekly newsletter.
Every Friday, you'll get a quick recap of all articles and tips posted on this site. No strings attached. Unsubscribe anytime.

Feel free to follow me on Twitter and ask your questions related to this post. Thanks for reading and see you next time.

If you enjoy my writing, please check out my Patreon https://www.patreon.com/sarunw and become my supporter. Sharing the article is also greatly appreciated.

Become a patron Buy me a coffee Tweet Share
Previous
A new way to manage the back button title in iOS 14 with backButtonDisplayMode

Apple adds a new way to control where the back button will pick up its title. Let's see how this make thing a lot easier going forward.

Next
How to Add inline images with text in SwiftUI

In iOS 14, we have a new way to put images along with texts.

← Home