iosswiftobjc-protocol

Check for optional multi-argument delegate methods


Newish to Swift. Struggling with how to get the most concise/idiomatic syntax for calling an optional delegate method if (a) the delegate is set and (b) the method is implemented.

I know the ? can play this role (eg self.delegate.foo?()) but I'm stymied getting syntax right when trying to call an ObjC delegate method that has multiple arguments and also returns a value (Bool) that I care about capturing (and I want to distinguish between "method not implemented" and "method implemented and returned false").

Here's an example. In this case, MyDelegateProtocol has an optional method -myThing:argTwo:argThree: (returns Bool).

This snippet seems to get the semantics right, but it uses respondsToSelector and is very chatty. Can it be improved in a more idiomatic way?

if let delegate = self.delegate {
    if delegate.respondsToSelector(#selector(MyDelegateProtocol.myThing(_:argTwo:argThree:))) {
        if delegate.myThing!(self, argTwo: foo, argThree: bar) {
            // do something
        }
    }
}

Solution

  • This code should work fine with optionals. And that is all you need to write.

    delegate?.myThing?(self, argTwo: foo, argThree: bar)
    

    This code should handle all cases that you were trying to check, e.g.:

    if let result = delegate?.myThing?(self, argTwo: foo, argThree: bar) {
         // "result" is the Bool returned from the method
    }
    

    If it enters than it means that your method exists and delegate is set. The only problem that may appear is if your method returns an optional Bool? (or any optional) type. Than you can't be sure that your logic is correct and you need to use some sort of checking that you performed in your question. Still in most cases it's unnecessary to know if such method exists, you just calling it if it exists and not calling if not, and my code will handle it.