John Montgomery
John Montgomery

Reputation: 7096

Method using the calling object's "self" by default

I have a utility class containing functions that are used by multiple other classes. One of those is an alert function:

class Utils {
    func doAlert (title: String, message: String, target: UIViewController) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "Close", style: .cancel, handler: nil))
        target.present(alert, animated: true, completion: nil)
    }
}

This function will always target self on the view controller, so I'd like to not have to add target: self every time I call the function, but I can't just set it as a default value since that causes it to refer back to the Utils class. Is there any way I can rewrite this to avoid that?

Upvotes: 2

Views: 58

Answers (2)

Sulthan
Sulthan

Reputation: 130102

Utility classes are an antipattern exactly for this reason, what you really want to use is an extension:

extension UIViewController {
    func doAlert(title: String, message: String) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "Close", style: .cancel, handler: nil))
        self.present(alert, animated: true, completion: nil)
    }
}

and then you can call the method directly on all your controllers:

self.doAlert(title: "title", message: "message")

In general avoid classes with utility methods. Try to add methods to the types to which the functionality actually belongs.

Upvotes: 4

ClayJ
ClayJ

Reputation: 432

Instead of putting the function in your Utils class, you could put it in an extension to UIViewController, like this:

    extension UIViewController {
        func doAlert (title: String, message: String) {
            let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "Close", style: .cancel, handler: nil))
            target.present(alert, animated: true, completion: nil)
      }

Upvotes: 2

Related Questions