Patriks
Patriks

Reputation: 1012

Extend a generic class in swift

I have some code which has to be available on all UIViewController of application. So I created a class UIViewControllerExtension: UIViewController, which will be extended by each class which I want to use as UIViewController. Which works as expected.

Now I have new screens where I have to use UITableViewController, so I can't extend same class UIViewControllerExtension, And to keep code centralized so I do not want to create another class UITableViewControllerExtension with same code, and want to have a common solution for both cases.

I tried various ways to extend generic class <T:UIViewController> so I can use it in both cases, but it didn't work (as it wouldn't compile). I did some research on internet but didn't find any solution to it. Does someone had same issue and have a solution?

I thought if there would be some solution like

class  CommonViewController<T:UIViewController>: T{    //I know it doesn't compile
//...
}

Usage:

class MyHomeScreenViewController: CommonViewController<UIViewController>{
}

class MyItemListScreenViewController: CommonViewController<UITableController>{
}

I am open to any other solution if it solves my problem.

Edit: More details

1> I would like to extend viewDidLoad() method of UIViewController and UITableViewController in common way (no duplication of code as said before)

2> I would like to add some supporting methods to UIViewController (and UITableViewController), supporting methods like navigateBack, loginUser(name:String,password:String) etc..

Upvotes: 0

Views: 3054

Answers (1)

Qbyte
Qbyte

Reputation: 13243

A solution would be to extend UIViewController to add additional functionality to all UIViewControllers and override viewDidLoad in your own classes:

extension UIViewController {
    func navigateBack() {
        ...
    }

    // an extension cannot override methods
    // so this method gets called later in an overridden viewDidLoad
    func viewDidLoadNavigate() {
        ...
    }
}

// you own classes
class MyHomeScreenViewController: UIViewController {

    // you have to make sure that all view controllers which can navigate override viewDidLoad
    override viewDidLoad() {
        // optional call to super
        super.viewDidLoad()
        // this is needed and called from the extension
        viewDidLoadNavigate()
    }
}

class MyItemListScreenViewController: UITableViewController {

    override viewDidLoad() {
        super.viewDidLoad()
        viewDidLoadNavigate()
    }
}

As you can see there is some code duplication but this is necessary since UITableViewController can also override viewDidLoad.

If generic inheritance is possible some day this code duplication can be reduced.

Upvotes: 2

Related Questions