dimroc
dimroc

Reputation: 1194

Elegant way to pass empty closures in Swift

In Swift, I often have to pass a noop closure to a method just to comply with the method's expected parameters (arity). In the good old days of Obj C, one could pass nil for a noop callback and be done with it. Is there a quicker more elegant way to do that in Swift without passing an empty block like below?

UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: { (UIAlertAction) -> Void in }) // do nothing in callback

Complete example:

import UIKit

class UIAlertControllerFactory {
    class func ok(title: String, message: String) -> UIAlertController {
        var alertController = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
        var okAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: { (UIAlertAction) -> Void in
        })
        alertController.addAction(okAction)
        return alertController
    }
}

Upvotes: 34

Views: 25697

Answers (4)

rob mayoff
rob mayoff

Reputation: 385890

In this case, you can pass nil, because the handler is an Optional:

var okAction = UIAlertAction(title: "Ok", style: .default, handler: nil)

The general way, if you can't pass nil:

var okAction = UIAlertAction(title: "Ok", style: .default, handler: { _ in })

Upvotes: 55

Leslie Godwin
Leslie Godwin

Reputation: 2658

You could define a noop to be used as a default closure that does nothing: (Reference: https://realm.io/news/closures-api-design)

func noop() {}

func noop<T>(value: T) {}

func noop<T>() -> T? { return nil }

func noop<T, S>(value: T) -> S? { return nil }

To use:

var okAction = UIAlertAction(title: "Ok", 
                             style: UIAlertActionStyle.Default, 
                           handler: noop)

Upvotes: 10

Imanou Petit
Imanou Petit

Reputation: 92549

According to Xcode documentation, UIAlertAction has a convenience init method with the following declaration:

convenience init(title: String, style: UIAlertActionStyle, handler: ((UIAlertAction!) -> Void)!) 

As you can see, the handler parameter is an Implicitly Unwrapped Optional of type ((UIAlertAction!) -> Void)!. So you may pass nil for it. For example, you can create an UIAlertController instance that contains one UIAlertAction with handler: nil:

let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)
alertController.addAction(UIAlertAction(title: "Cancel", style: .Cancel, handler: nil))
presentViewController(alertController, animated: true, completion: nil)

Therefore, you don't need to create an empty block for handler.

Upvotes: 5

Mundi
Mundi

Reputation: 80271

extension UIAlertAction {
    convenience init(title: String, style: UIAlertActionStyle) {
        return self.init(title: title, style: style, handler:  { (UIAlertAction) -> Void in })
    }
}

and just leave out the last argument. You can put this into your "factory".

Upvotes: 3

Related Questions