3

I'm using Xcode 8 and swift 3. I have the following error on line "let action": #selector' refers to a method that is not exposed to Objective-C Any suggestion ?

   override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cellWaze", for: indexPath) as! WazeTableViewCell

    // Configure the cell...
    cell.lbAgence.text = aWAgence[indexPath.row][0] as? String
    let cellLat :Double = aWAgence[indexPath.row][1] as! Double
    let cellLong :Double = aWAgence[indexPath.row][2] as! Double

    cell.bWaze.tag = indexPath.row
    let action = #selector(LaunchWaze(cellLat,longitude: cellLong))
    cell.bWaze.addTarget(self, action: action, for: .touchUpInside)

    return cell
}

@objc func LaunchWaze(_ latitude: Double, longitude: Double) {
    if UIApplication.shared.canOpenURL(NSURL(string: "waze://")! as URL) {
        // Waze is installed. Launch Waze and start navigation
        var urlStr = "waze://?ll=\(latitude),\(longitude)&navigate=yes"
        print("url : \(urlStr)")
        //UIApplication.shared.openURL(NSURL(string: urlStr)!)
    }
    else {
        // Waze is not installed. Launch AppStore to install Waze app
        UIApplication.shared.openURL(NSURL(string: "http://itunes.apple.com/us/app/id323229106")! as URL)
    }
}
Rodolphe
  • 55
  • 1
  • 3
  • Possible duplicate of ['#selector' refers to a method that is not exposed to Objective-C](http://stackoverflow.com/questions/36818083/selector-refers-to-a-method-that-is-not-exposed-to-objective-c) – Shaked Sayag Apr 05 '17 at 20:10

2 Answers2

5

Try to inherit NSObject to your class.

class YourClass {
  ...
}

to

class YourClass: NSObject {
  ...
}
2

You cannot include actual parameters into selectors.

And the method for action target can take only three forms:

UIControl

Listing 1 Action method definitions

    @IBAction func doSomething()
    @IBAction func doSomething(_ sender: UIButton)
    @IBAction func doSomething(_ sender: UIButton, forEvent event: UIEvent)

(I added _ before sender, but it is not mandatory, just you need to create a consistent selector. UIButton can be any appropriate UIControl subclass, or just Any if you do not think of what it should be. @IBAction can be replaced with @objc when adding the method programatically, in many cases, which is implicitly added.)

So, if you want to pass some info to the action method, you need to put it in sender or use some intermediate instance properties.


In your case, a quick fix would be something like this.

The selector should be:

    let action = #selector(launchWaze(_:))

And the method:

@objc func launchWaze(_ sender: UIControl) {
    let latitude: Double = aWAgence[sender.tag][1] as! Double
    let longitude: Double = aWAgence[sender.tag][2] as! Double

    //...        
}
OOPer
  • 47,149
  • 6
  • 107
  • 142