1

I have a method declared in Objective-C protocol:

@protocol QMChatConnectionDelegate <NSObject>
@optional
- (void)chatServiceChatDidConnect:(QMChatService *)chatService;

I want to use this method as callback in my .swift file. My question what is difference between using chatServiceChatDidConnect method directly in class body or adding it as part of extension:

class Chat: NSObject, QMChatConnectionDelegate
{
...
  func chatServiceChatDidConnect(chatService: QMChatService!) {
    print("connected")
  }
}

or

class Chat: NSObject, QMChatConnectionDelegate
{
...
}

extension Chat: QMChatConnectionDelegate {
    func chatServiceChatDidConnect(chatService: QMChatService!) {
        print("connected")
    }
}

and do I need to declare it as extension Chat : QMChatConnectionDelegate {} or just extension Chat {}

nhgrif
  • 61,578
  • 25
  • 134
  • 173
Matrosov Oleksandr
  • 25,505
  • 44
  • 151
  • 277
  • If the Objective-C protocol is of your creation, you should add [Objective-C nullability annotations](http://stackoverflow.com/a/29401454/2792531) to get rid of that really ugly implicitly unwrapped optional in Swift. – nhgrif Mar 04 '16 at 13:45
  • @nhgrif nope, it's from library... but thanks for the link) – Matrosov Oleksandr Mar 04 '16 at 14:11

2 Answers2

2

First of all extension declaration is valid only from the file scope, so your second example should look like that:

class Chat: NSObject
{
...
}

extension Chat : QMChatConnectionDelegate {
  func chatServiceChatDidConnect(chatService: QMChatService!) {
    print("connected")
}

Secondly you shouldn't re-declare protocol conformance in both class declaration and extension.

You should treat Swift extension more or less like categories in Objective-C.

Answering your questions, there is no big difference if you declare method conforming to a protocol directly in the class scope or in the extension. Adding protocol conformance in extensions can have several benefits:

  1. You can add methods implementing certain protocol in a separate file
  2. You can add protocol conformance to existing classes, without modifying their body. So in the end you can add protocol conformance to 3rd party classes
  3. It allows for a nice logical organization of your source code.
tgebarowski
  • 1,189
  • 11
  • 14
2

There are two questions being asked here, so I'll try to address both of them as directly as possible.


What is difference between using chatServiceChatDidConnect method directly in class body or adding it as part of extension?

Depending on what you mean by "difference", the answer is either "nothing" or "very little".

Once your project is compiled, there will be no difference. During compilation, it might take slightly longer, but I doubt the difference is noticeable enough to care. During development, the difference is mostly organizational, but perhaps partly architectural.

If you do not move the extension to a separate file, the difference is going to be purely organizational. If you have a class conforming to multiple protocols or particularly large protocols, organizing the protocol conformance into extensions can be beneficial when it comes to human-parsing of the class.

If you do move the extension into a separate file, you can obtain some architectural differences as well when we consider how the private access modifier works in Swift (or also the default internal when we consider that the extension could be not just a different file, but a different module, but for simplicity sake, let's focus on private).

Consider conforming to a UITableViewDataSource protocol. Conceivably, we might want some helper methods when it comes to returning a cell from tableView(_:cellForRowAtIndexPath:), and if that's the case, tableView(_:cellForRowAtIndexPath:) is probably the only method that actually needs to call those methods. If that's the case, we can create the protocol conformance in an extension in a separate file and mark all of the helper methods as private. Now we've narrowed the scope of those helper methods to just that extension (which should be the only place that needs it).


Do I need to declare it as extension Chat: QMChatConnectionDelegate {} or just extension Chat {}?

The answer to this is it depends.

Certainly, you don't need to mark your class as conforming to a protocol in multiple places. Just one will do. And while extensions can have different access level than the class they extend (a private extension of an internal class for example), they can not have an access level broader than the class they extend (a public extension of an internal class is not allowed, for example).

What makes most sense to me is to not mark the class as conforming to the protocol but mark the extension as conforming to the protocol:

class Chat: NSObject {}
extension Chat: QMChatConnectionDelegate {}

Importantly, when we create our classes & extensions like this, it keeps our code quite modular. Our class shouldn't rely on anything in the extension. It should function entirely without it, and removing the extension allow our class to still work properly (just not for using the QMChatConnection).

nhgrif
  • 61,578
  • 25
  • 134
  • 173