Michael
Michael

Reputation: 33297

Check if optional protocol method is implemented in Swift?

I have a swift protocol:

@objc protocol SomeDelegate {

  optional func myFunction()

}

I one of my classes I did:

weak var delegate: SomeDelegate?

Now I want to check if the delegate has myFunction implemented.

In objective-c I can do:

if ([delegate respondsToSelector:@selector(myFunction)]) { 
...
}

But this is not available in Swift.

Edit: This is different from: What is the swift equivalent of respondsToSelector? I focus on class protocols not on classes.

How do I check if my delegate has an optional method implemented?

Upvotes: 35

Views: 25861

Answers (6)

Wonjae Oh
Wonjae Oh

Reputation: 33

I know this question is 5 years old, but I would like to share what I found. My solution works as of 2021, XCode 11+, Swift 5.

enter image description here

Say I wanted to figure out whether the function sign follows the GIDSignInDelegate protocol and also know what all the optional functions for GIDSignInDelegate are.

I have to look at the source code of the GIDSignIn module, and this is how.

enter image description here

Click on jump to definition on the main module that is imported. It will lead to a file like this:

enter image description here

Copy the entire line, import GoogleSignIn.GIDSignIn and paste it in the ViewController or whatever .swift file (doesn't really matter).

Within the swift file, right click on the GIDSignIn part of the import line GoogleSignIn.GIDSignIn and jump to definition. This will lead you to the actual module with all the available functions (the functions not marked optional may be stubs, which are required functions in the delegate protocol):

enter image description here

From this file, I can see that there is a sign function that is a stub of GIDSignInDelegate and an optional sign function that is implemented as a method overload.

I used this for GIDSignInDelegate, but you can use the same method to figure out whether any function follows any delegate protocol.

Upvotes: 0

Sergio Estevao
Sergio Estevao

Reputation: 21

I normally implement it like this:

self.delegate?.myFunction?()

if the delegate methods returns a value:

var result = defaultValue
if let delegateResult = self.delegate?.myFunction?() else {
  result = delegateResult
}

//do something with result

Upvotes: 2

Darshit Shah
Darshit Shah

Reputation: 2382

Declaration

@objc public protocol nameOfDelegate: class {
    @objc optional func delegateMethod(_ varA: int, didSelect item: Item)
}

Implimetation

if let delegate = nameOfDelegate {
     delegate.delegateMethod?(1, didDeselect: node)
}

Upvotes: 0

Chris
Chris

Reputation: 2747

I've found it successful to add an extension to the protocol that defines basic default implementation and then any class implementing the protocol need only override the functions of interest.

    public protocol PresenterDelegate : class {
        func presenterDidRefreshCompleteLayout(presenter: Presenter)
        func presenterShouldDoSomething(presenter: Presenter) -> Bool
    }

then extend

    extension PresenterDelegate {
        public func presenterDidRefreshCompleteLayout(presenter: Presenter) {}
        public func presenterShouldDoSomething(presenter: Presenter) -> Bool {
        return true
        }
    }

Now any class needing to conform to the PresenterDelegate protocol has all functions already implemented, so it's now optional to override it's functionality.

Upvotes: 8

newacct
newacct

Reputation: 122429

You can do

if delegate?.myFunction != nil {

}

Upvotes: 17

Tommy
Tommy

Reputation: 100622

Per The Swift Programming Language:

You check for an implementation of an optional requirement by writing a question mark after the name of the requirement when it is called, such as someOptionalMethod?(someArgument). Optional property requirements, and optional method requirements that return a value, will always return an optional value of the appropriate type when they are accessed or called, to reflect the fact that the optional requirement may not have been implemented.

So the intention is not that you check whether the method is implemented, it's that you attempt to call it regardless and get an optional back.

Upvotes: 31

Related Questions