Honey Honey - 9 days ago 6
Swift Question

How should you handle closure arguments for UIAlertAction

I have been trying to create a

UIAlertAtion
which also has a handler. I read the answers from this question and know how to do it.

My question is only about the closure portion of it.

1) I know I can write :
{alert in println("Foo")}
Or
{_ in println("Foo")}
but I can't write
{println("Foo")}
. In the comments here it is explained because you need to handle the argument action.

Does this mean that since the handler is of type
(UIAlertAction) -> Void)?
I must always capture the passed alertAction?




2)
I also read this and the answer is basically saying you can pass in a function as your argument, but the function should take something of type
UIAlertAction -> Void
, which I wrote :

private func anything(action : UIAlertAction) {
print("hello")
}


and then wrote my alertaction as such:

let anotherAction = UIAlertAction(title: "hi", style: UIAlertActionStyle.Default,
handler: anything(action)) // error: Use of unresolved identifier 'action'


confused why I get that error




3)
In the comments it also said: But in addition to that you don't have to write UIAlertActionStyle.Default in swift. .Default works, too

I tried writing not using the style so it would be defaulted to
.Default


let sendLogAction = UIAlertAction(title: "Log") { action in print("goodbye")}


But then I get the following error:


'(title: String, (_) -> ())' (aka '(title: String, _ -> ())') is not
convertible to '(title: String?, style: UIAlertActionStyle, handler:
((UIAlertAction) -> Void)?)' (aka '(title: Optional, style:
UIAlertActionStyle, handler: Optional ()>)'), tuples
have a different number of elements





4)
Also reading this answer. I don't understand why we need to pass in
alert
it makes no sense. It's not like we don't know what are alert's type is...haven't we already defined its type?!! Can anyone explain where passing the action itself would be useful in general, I mean what could we do with it?




I know this is wrote as 4 questions but I think it's really just a foundational question. I have extensively read, used closures/completion handlers in a project I'm working and played in playground but still I'm confused.

Answer
  1. Yes, you must always handle the argument. It's part of the signature and can't be ignored. It's also special Swift syntax being able to drop the handler parameter since it is the last parameter and it is a closure parameter.

  2. Change anything(action) to anything just like in the example you link to.

  3. You misunderstand. They are not saying you can drop the style parameter. They are saying you can drop the UIAlertActionStyle from UIAlertActionStyle.Default meaning you only need to pass .Default as the argument to the style parameter.

  4. You want an example of where the action parameter to the handler is useful. There aren't too many uses really. The only properties are the title, style, and whether it's enabled or not. The latter is pointless because if the handler was called you know it was enabled. The only possible use is if the title or style need to be used in the handler and they weren't hard coded into the alert action when it was created. By accessing the title or style properties in the handler, you have easy access to the actual values used when the action was created.