0

I have an extension to UIAlertController that I am using to show a pop-up of the Terms of Service in my app.

I would like to have two versions of this pop-up: One where the user can accept or decline the ToS (to be displayed on first use of the app), and one where the user can read over them and then dismiss the pop-up (to be displayed in the settings screen at any time).

The two pop-ups are extremely similar, so instead of rewriting the same function twice, I'd rather create another function that calls termsOfServiceAlert() with modified arguments. However, since the user should only be able to dismiss the ToS when termsOfServiceAlternativeAlert() is called, I need to make the accept and decline arguments optional. I know how to do this for normal variables, but I can't find a way to make it work for functions that are passed as arguments.

Here is the code snippet:

extension UIAlertController {

    static func termsOfServiceAlert(
        title: String,
        message: String?,
        acceptText: String,
        accept: @escaping ()->Void,
        declineText: String,
        decline: @escaping ()->Void) -> UIAlertController {

            /* set up alert */

            let acceptTermsHandler: (UIAlertAction) -> Void = { (alertAction in
                accept()
            }

            let declineTermsHandler: (UIAlertAction) -> Void = { (alertAction in
                decline()
            }

            let accept = "Accept"
            alert.addAction(UIAlertAction(title: accept, style: .default, handler: acceptTermsHandler

            let decline = "Decline"
            alert.addAction(UIAlertAction(title: decline, style: .default, handler: declineTermsHandler

            return alert
    }

    static func termsOfServiceAlternativeAlert(message: String, dismiss: String) -> UIAlertController {
        /* ERROR - Nil is not compatible with expected argument type '() -> Void */
        return termsOfService(
            message: message, 
            acceptText: dismiss, 
            accept: nil, 
            declineText: nil, 
            decline: nil)
    }
}
Swifty
  • 839
  • 2
  • 15
  • 40

1 Answers1

0

You need to make those arguments as optional and then pass as nil. here is the fix,

extension UIAlertController {

    static func termsOfServiceAlert(
        title: String,
        message: String?,
        acceptText: String,
        accept: (()->Void)?,
        declineText: String?,
        decline: (()->Void)?) -> UIAlertController {

        /* set up alert */

       let alert = UIAlertController.init(title: title, message: message, preferredStyle: .alert)
       let acceptTermsHandler: (UIAlertAction) -> Void = { alertAction in
          accept?()
       }

       let declineTermsHandler: (UIAlertAction) -> Void = { alertAction in
           decline?()
        }

       alert.addAction(UIAlertAction(title: "Accept", style: .default, handler: acceptTermsHandler))

       alert.addAction(UIAlertAction(title: "Decline", style: .default, handler: declineTermsHandler))

       return alert
  }

    static func termsOfServiceAlternativeAlert(message: String, dismiss: String) -> UIAlertController {
        /* ERROR - Nil is not compatible with expected argument type '() -> Void */
        return termsOfServiceAlert(
            title: "", 
            message: message,
            acceptText: dismiss,
            accept: nil,
            declineText: nil,
            decline: nil)
    }
}
Kamran
  • 14,987
  • 4
  • 33
  • 51
  • Thanks Kamran. I am curious as to why we need to remove `@escaping` when passing the function as an `optional`! – Swifty Oct 24 '18 at 17:29