0

I am trying to refactor my UIAlertViewController and pass a function to be executed when a user chooses to tap on one of two options which triggers an action.

My question is how do I go about adding a function as a parameter to a custom function? My effort is below. It is incomplete but any guidance would be much appreciated. I would like to have the function 'performNetworkTasl' as a parameter to 'showBasicAlert'.

import Foundation
import UIKit



struct Alerts {
static func showBasicAlert(on vc: UIViewController, with title: String, message: String, function: ?????){

    let alert =  UIAlertController.init(title: title, message: message, preferredStyle: .alert)

    let okAction = UIAlertAction.init(title: "OK", style: .default) { (UIActionAlert) in

        performNetworkTasl()

        vc.dismiss(animated: true, completion: nil)
    }

    alert.addAction(okAction)
}
}


func performNetworkTasl(){
  // DO SOME NETWORK TASK
}
Rakesh Patel
  • 1,673
  • 10
  • 27
dean
  • 321
  • 3
  • 17
  • Why do you want to pass the function as a parameter when you have already called underneath okAction? – Rob Sep 10 '18 at 07:45
  • It should be parameter ```function: @escaping () -> Void```. It will accept closues/functions with same signature ```() -> Void``` To cal it: ```showAlert(on: vc, with: "", message: "", function: performNetworkTasl)``` – Modo Ltunzher Sep 10 '18 at 07:54

1 Answers1

3

You wouldnt pass a function as such, rather would pass a closure as a argument. Functions in swift are special cases of closure. Closure can be assumed to be a anonymous function. Closures,instant methods and static methods they all vary only in their context capturing ability other than their obvious syntactic differences.

struct Alerts {
        static func showBasicAlert(on vc: UIViewController, with title: String, message: String, okAction: @escaping (() -> ())){

            let alert =  UIAlertController.init(title: title, message: message, preferredStyle: .alert)

            let okAction = UIAlertAction.init(title: "OK", style: .default) { (UIActionAlert) in

                okAction()

                //dismiss statement below is unnecessary
                vc.dismiss(animated: true, completion: nil)
            }

            alert.addAction(okAction)
        }
    }

And you call the function as

    Alerts.showBasicAlert(on: your_viewController, with: "abcd", message: "abcd", okAction: {
        //do whatever you wanna do here
    })

Hope this helps

BTW, you dont have to have a explicit vc.dismiss(animated: true, completion: nil) as a last statement in any action, once the action is triggered, UIAlertController is dismissed by default

Sandeep Bhandari
  • 19,999
  • 5
  • 45
  • 78