Samuel Clay Samuel Clay - 2 months ago 68
Swift Question

NSSelectorFromString with named parameters in Swift 3

In Swift 2.3 I could dynamically call methods that had named parameters using

NSSelectorFromString("methodWithArg:")
. In Swift 3 I have to prepend
_
to a named parameter to allow it to be called without its name.

Is this still possible? See this playground code for a test case.

class Parent : NSObject {
func parentSelector(_ arg: String) {
print(" ---> Selected: \(arg)")
}
func test(_ selectorString: String, _ printString: String) {
let selector : Selector = NSSelectorFromString(selectorString)
// if self.responds(to: selector) {
self.perform(selector, with: printString)
// }
}
}

class Child : Parent {
func childSelector(_ arg: String) {
print(" ---> Child selected: \(arg)")
}
func namedChildSelector(arg: String) {
print(" ---> Child selected: \(arg)")
}
}

let parent = Parent()
parent.test("parentSelector:", "apple") // Works

let child = Child()
child.test("parentSelector:", "banana") // Works
child.test("childSelector:", "coffee") // Works
child.test("namedChildSelector:", "daffodil") // Throws `NSInvalidArgumentException`
child.test("namedChildSelector(_:)", "daffodil") // Throws `NSInvalidArgumentException`

Answer

In Swift 3, the first parameter name is part of the selector name, so you need to add WithArg if the first argument name is arg:

child.test("namedChildSelectorWithArg:", "daffodil")