Since WWDC we've been made well aware that Swift wants you to protocol all of the things. This is extremely useful when using a Swift project. When incrementally converting a project that has both Swift and Objective-C, adopting these very Swifty conventions can be more difficult.

Protocol Extensions

Protocol extensions are, among other things, a way to provide a default implementation to a protocol method.

protocol MyProtocol {
    func myMethod()
}

This defines a protocol (MyProtocol) and defines a protocol method, myMethod(). Classes that implement this protocol must provide an implementation of myMethod(). That's essentially what protocols are.

A protocol extension allows you to define a default implementation of an protocol method.

extension MyProtocol {
    func myMethod(){
        print("Default implementation!")
    }
}

Cool. Now classes (and structs) implementing this protocol can either implement their own implementation of myMethod(), or they can rely on the default implementation. Protocol extensions are a main reason why protocols are so powerful in Swift.

The Objective-C Wet Blanket

Objective-C has protocols as well. It can even use Swift protocols (well, at least those that are marked with the objc attribute). What it can't do, however, is use those default implementations declared in protocol extensions. To Objective-C, protocols are just a map to the messages an object can or cannot receive. It doesn't get the concept of default implementations. So what do you do if you need to work with Objective-C, but want default implementations?

In this case, we can adopt a pattern that Objective-C itself uses for NSObject. It's not exactly pretty and requires class inheritence, which is something we were trying to get away from with protocols, but it works and can be used as a stop-gap measure until we've refactored out the last of the Objective-C from our apps.

Objective-C has an object called NSObject. This is no surprise as almost every class in Cocoa and our own apps subclass NSObject. However, you don't have to subclass NSObject in order to to play nice with Cocoa which really, really likes NSObject. What you have to do instead, is adhere to the NSObject protocol. So, NSObject is both a class and a protocol in Objective-C. There are even some classes in Cocoa, such as NSProxy that take this approach.

The NSObject protocol defines methods like isEqual:, hash, isKindOfClass and many others.. Ninety-nine percent of the time, you'll simply want to subclass NSObject so you won't have to implement all of these classes yourself; you can just rely on the, wait for it, default implementation.

You can probably see where I am going with this.

A Protocol By Any Other Name

So, let's say with the protocol we defined above, MyProtocol, we want to use default implementations in Swift and Objective-C. In order to accomplish this, we'll need to define our protocol in Objective-C, not Swift. Let's also change the name to MyObject while we're at it, since it will make more sense in this situation.

@protocol MyObject
- (void)myMethod;  
@end

Now, in order to define our default implementation, we'll create a class with the same name.

// MyObject.h
@interface MyObject: NSObject
- (void)myMethod;
@end

// MyObject.m
@implementation MyObject
- (void)myMethod 
{
    NSLog(@"Default implementation!");  
}  
@end

Now we have a protocol and a default implementation. To use this in an Objective-C class, we now do this:

@interface CoolObject: MyObject
@end

CoolObject both subclasses MyObject and conforms to the MyObject protocol. It can rely on myMethod defined in the class or it can define its own.

So what is the advantage of this over straight subclassing? Let's see how we implement this in Swift to see.

MyObject and MyObjectProtocol

Swift won't let you have a protocol and a class with the same name. This isn't a problem, it'll just just tack on "Protocol" to the name of the protocol in question in order to distinguish the two. (It imports NSObject as NSObject and NSObjectProtocol.)

Since we have MyObject and MyObjectProtocol to work with, we can either conform to MyObjectProtocol and implement our own myMethod or we can additionally subclass MyObject in order to get the default implementation. Our app passes around the MyObjectProtocol definition, which is super Swifty and our classes can either be MyObject subclasses or not.

No, it isn't as good as protocol extensions as it still requires subclassing which is oh-so-not-Swifty, but when playing in the sandbox with Objective-C and Swift, we sometimes have to make some compromises in order to have Objective-C know what's going on and keeping the compiler happy. It's not perfect, but it gives us optional default implementations in both Objective-C and Swift until the day we can sweep Objective-C out the door of our app entirely.