2

I have two main screens in my app, currently both just subclasses of UIViewController. These two view controllers are very similar - they both implement my custom subclass of UIView called HeaderView that is responsible for displaying information and taking user input. As it stands, this code is repetitive because the HeaderView setup is the same for both view controllers - the only difference is what happens when the user confirms the text entry in HeaderView.

To cut down on repetitive code, I am creating a class called InputViewController (a subclass of UIViewController) that houses the aspects of the two view controllers that are identical. Eventually, I want the two view controllers to subclass InputViewController instead of UIViewController.

class InputViewController: UIViewController, InputProtocol {

    private let headerView = HeaderView()
        
    override func viewDidLoad() {
        super.viewDidLoad()
        // layout, etc.
        setupCallbacks()
    }
    
    internal func setupCallbacks() {
        headerView.onUpdate = { (text: String) in
            // called when user confirms text entry in headerView
            self.onHeaderUpdate()
        }
    }
    
    internal func onHeaderUpdate() {} // Blank function
    
}

setupCallbacks() and onHeaderUpdate() are methods defined in the protocol that the InputViewController conforms to. The HeaderView implements a callback closure that is handled in setupCallbacks() by headerView.onUpdate...

The protocol that InputViewController conforms to:

protocol InputProtocol {
    func setupCallbacks()
    func onHeaderUpdate()
}

To illustrate this, I drew up a diagram; diagram

Since I want the subclasses of InputViewController to override the onHeaderUpdate() method, is it conventional to leave the definition of onHeaderUpdate() in InputViewController blank or is there another solution to this?

gmdev
  • 2,725
  • 2
  • 13
  • 28

1 Answers1

2

is it conventional to leave the definition of onHeaderUpdate() in InputViewController blank

Yes, that is called an abstract method. It is common to give it code that crashes deliberately, as a way of saying, “I exist only to be overridden in a subclass.”

(I should go further and say that what you are creating, a base view controller that carries out initial configurations that all subclasses must implement, is also normal.)

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • Thank you for clarifying! I struggled to find answers on Google and SO because I wasn't familiar with the abstract method term. May be helpful to include this link: https://stackoverflow.com/questions/24110362/abstract-functions-in-swift-language – gmdev Sep 10 '20 at 14:36
  • As I’ve now pointed out in my answer, a base view controller that carries out initial configurations that all subclasses must implement is also normal. You have reinvented a very useful wheel! In some of my apps, all my view controllers do this. They all inherit and implement abstract configuration methods to set up views, colors, constraints, and so on, which are called by the base view controller. – matt Sep 10 '20 at 14:44
  • Awesome, it's good to know that my assumptions were normal and not completely wrong. This method of implementation is very helpful in reducing code and improving readability at the same time. All good things! – gmdev Sep 10 '20 at 14:52