Passing functions as parameters in Swift
Oneword answer for your question is Closures
The Default Syntax for closures is () -> ()
Instead of Selector you could directly mention the method definition
func showConfirmBox(msg:String, title:String, firstBtnStr:String, firstSelector:(sampleParameter: String) -> returntype, secondBtnStr:String, secondSelector:() -> returntype, caller:UIViewController) { //Your Code}
But using this will create readability problems so i suggest you to use typeAlias
typealias MethodHandler1 = (sampleParameter : String) -> Voidtypealias MethodHandler2 = () -> Voidfunc showConfirmBox(msg:String, title:String, firstBtnStr:String, firstSelector:MethodHandler1, secondBtnStr:String, secondSelector:MethodHandler2) { // After any asynchronous call // Call any of your closures based on your logic like this firstSelector("FirstButtonString") secondSelector()}
You can call your method like this
func anyMethod() { //Some other logic showConfirmBox(msg: "msg", title: "title", firstBtnStr: "btnString", firstSelector: { (firstSelectorString) in print(firstSelectorString) //this prints FirstButtonString }, secondBtnStr: "btnstring") { //Invocation comes here after secondSelector is called }}
Just in case anyone else stumbles upon this. I worked out an updated simple solution for Swift 5.1 while I was working through this for while building a global alert utility for a project.
Swift 5.1
Function with Closure:
func showSheetAlertWithOneAction(messageText: String, dismissButtonText: String, actionButtonText : String, presentingView : NSWindow, actionButtonClosure: @escaping () -> Void) { let alert = NSAlert() alert.messageText = messageText alert.addButton(withTitle: actionButtonText) alert.addButton(withTitle: dismissButtonText) alert.beginSheetModal(for: presentingView) { (response) in if response == .alertFirstButtonReturn { actionButtonClosure() } } }
Function Called:
showSheetAlertWithOneAction(messageText: "Here's a message", dismissButtonText: "Nope", actionButtonText: "Okay", presentingView: self.view.window!) { someFunction() }
Adding to got2jam's answer...If you're working with UIAlertController
The generic function to show an alert with closure:
func showAlertAction(title: String, message: String, actionClosure: @escaping () -> Void){ let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert) alertController.addAction(UIAlertAction(title: "Ok", style: UIAlertAction.Style.default, handler: {(action: UIAlertAction!) in actionClosure()})) self.present(alertController, animated: true, completion: nil)}
Now you can call it like that:
showAlertAction(title: "This is the title", message: "This is the message") { self.close()}
in this case, close is the particular UIAlertAction to execute
func close(){ dismiss(animated: true, completion: nil)}