As I was working on a toy iOS project today, I found myself typing in a bunch of boiler plate code to present errors with a UIAlertController. This resulted in me wondering if there was a way in which I could avoid repeating the same code over and over again.

My first solution to the problem was to create an extension on UIViewController:

extension UIViewController {

    func showError(title: String, message: String? = nil) {
        let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
        let dismissAction = UIAlertAction(title: "Dismiss", style: .Cancel, handler: nil)
        alertController.addAction(dismissAction)
        self.presentViewController(alertController, animated: true, completion: nil)
    }

}

I wasn’t particularly happy with this though, since this results in every UIViewController in my app having showError function. Not every one of them needs it, though. I figured there must be some way in Swift to opt each UIViewController into having this function one at a time. Here’s the best solution I came up with:

protocol ErrorPresenter {

    func showError(title: String, message: String)

}

extension ErrorPresenter where Self: UIViewController {


    func showError(title: String, message: String? = nil) {
        let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
        let dismissAction = UIAlertAction(title: "Dismiss", style: .Cancel, handler: nil)
        alertController.addAction(dismissAction)
        self.presentViewController(alertController, animated: true, completion: nil)
    }

}

Now, all I have to do to opt a particular UIViewController into having this function is have it conform to ErrorPresenter:

class MyViewController: UIViewController, ErrorPresenter {
    // stuff
}

The only problem I can think of with this solution is that you cannot have any internal state in this extension since extensions can’t have stored properties. This would prevent me from creating a CoalescedErrorPresenter, which could for instance keep track of all calls to showError, and only show a UIAlertController once every X seconds. If you can think of any solutions to this problem I’d love to know. Hit me up @gopalkri.

Gopal Sharma

gps gopalkri


Published