Swift Protocols constrained to a specific class

Update: As of Swift 4, this is supported natively. Just do this:

var controller: UIViewController & MyProtocol

That’s it!


Objective-C developers learning Swift often wonder how to represent something like UIViewController. The simple answer is that there’s currently no way to directly represent that construct in Swift as of Swift 2.2. However, it’s possible to work around it fairly easily with just a tiny bit of extra code.

protocol KitchenHelper: class {
// The normal protocol stuff here
func bakeCookies()
func eatCake()

// The new stuff
var asViewController: UIViewController { get }
}

We’ve added an additional constraint to the protocol; any object that implements KitchenHelper must be able to return a UIViewController as well. Presumably, any conforming view controller would want to simply return self, so lets make that easier:

extension KitchenHelper 
    where Self: UIViewController 
{
    // Let's provide a default implementation 
    // for view controllers
    var asViewController: UIViewController { 
        return self 
    }
}

Now any view controller class that conforms to KitchenHelper will automatically implement asViewController as well!

class MyViewController: UIViewController, KitchenHelper {
func bakeCookies() {
// sugar, flour, eggs...
}

func eatCake() {
// yum
}

// 'asViewController' was automatically implemented!
}

func test() {
let helper: KitchenHelper = MyViewController()
let frame = helper.asViewController.view.frame
print("helper's view's frame:", frame)
}

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: