Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift generic type property and method

How do I store generic type in property and then use that type property to pass in method?

I have factory whose method receives view controllers type but returns instance of that view controller (container takes care of that).

public protocol ViewControllerFactoryProtocol {
    func getViewController<T: UIViewController>(type: T.Type) -> UIViewController
}

public class ViewControllerFactory: ViewControllerFactoryProtocol {

private let container: Container

public init(container: Container) {
    self.container = container
}

public func getViewController<T: UIViewController>(type: T.Type) -> UIViewController {
    return self.container.resolve(type)!
}

}

And I have property like this

var destinationViewController: UIViewController.Type { get }

Now I would like to do something like:

factory.getViewController(self.destinationViewController)

where I declare destinationViewController as LoginViewController.self

But its not working like that. Weird thing is that it is working if I do it directly:

factory.getViewController(LoginViewController.self)

Any help?? Thanks

like image 927
zhuber Avatar asked Feb 12 '26 22:02

zhuber


1 Answers

Without seeing the code for resolve it's not possible to say why it's crashing, but I have a good idea. I suspect you're mistaking the difference between generic type parameters and runtime type parameters. Consider this simplified code.

func printType<T>(type: T.Type) {
    print("T is \(T.self)")
    print("type is \(type)")
}

class Super {}
class Sub: Super {}

printType(Super.self) // Super/Super. Good.
printType(Sub.self)   // Sub/Sub. Good.

let type: Super.Type = Sub.self
printType(type) // Super/Sub !!!!!!

Why is the last case Super/Sub? Because printType<T> is resolved at compile time. It looks just at the definitions:

func printType<T>(type: T.Type)
let type: Super.Type

printType(type)

To make this work, I need a T such that T.Type is the same as Super.Type. Well, that's Super. So this gets compiled as:

printType<Super>(type)

Now at runtime, we see that type is equal to Sub.self, which is a subtype of Super.type, so that's ok. We pass it along to printType<Super> and get the response you're seeing.

So probably internal to resolve, you're using T somewhere that you wanted to use type, and that you're trying to "resolve" UIViewController, which probably returns nil.

like image 90
Rob Napier Avatar answered Feb 15 '26 11:02

Rob Napier



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!