How can I assign a default action to UIButton to show an alert unless
  another action is assigned via interface builder or programmatically?
I would suggest to do method swizzling:
Through swizzling, the implementation of a method can be replaced with
  a different one at runtime, by changing the mapping between a specific
  selector(method) and the function that contains its implementation.
https://www.uraimo.com/2015/10/23/effective-method-swizzling-with-swift/
Remark: I would recommend to check the article above.
As an exact answer for your question, the following code snippet should be -in general- what are you trying to achieve:
class ViewController: UIViewController {
    // MARK:- IBOutlets
    @IBOutlet weak var lblMessage: UILabel!
    // MARK:- IBActions
    @IBAction func applySwizzlingTapped(_ sender: Any) {
        swizzleButtonAction()
    }
    @IBAction func buttonTapped(_ sender: Any) {
        print("Original!")
        lblMessage.text = "Original!"
    }
}
extension ViewController {
    func swizzleButtonAction() {
        let originalSelector = #selector(buttonTapped(_:))
        let swizzledSelector = #selector(swizzledAction(_:))
        let originalMethod = class_getInstanceMethod(ViewController.self, originalSelector)
        let swizzledMethod = class_getInstanceMethod(ViewController.self, swizzledSelector)
        method_exchangeImplementations(originalMethod, swizzledMethod)
    }
    func swizzledAction(_ sender: Any) {
        print("Swizzled!")
        lblMessage.text = "Swizzled!"
    }
}
After calling swizzleButtonAction() -by tapping the "Apply Swizzling" button (applySwizzlingTapped)-, the selector of "Button" should changed from buttonTapped to swizzledAction.
Output:
