简体   繁体   English

Swift、iOS:如何从具体类型中获取多态和解耦协调器

[英]Swift, iOS: How to get Polymorphic and Decouple Coordinator from concrete type

I have these protocols:我有这些协议:

protocol Coordinator {
    var rootViewController: UIViewController { get set }
    func start()
}

protocol UIViewControllerFactory {
    func mainViewController() -> UIViewController
}

And I created a MainCoordinator that conforms to this protocol and I pass a factory that allows me to decouple the coordinator from creating and capturing a concrete type so it can be polymorphic and can be used with more implementations of UIViewController either as rootViewControllers and mainMenuViewController as shown below:我创建了一个符合此协议的MainCoordinator并传递了一个工厂,该工厂允许我将协调器与创建和捕获具体类型分离,因此它可以是多态的,并且可以与UIViewController的更多实现一起使用,如rootViewControllersmainMenuViewController所示以下:

class MainCoordinator: Coordinator {
    var rootViewController: UIViewController
    let factory: UIViewControllerFactory 
    
    init(rootViewController: UIViewController, factory: UIViewControllerFactory) {
        self.rootViewController = rootViewController
    }
    
    start() {
        guard let mainVC = factory.mainViewController() as? MainViewController, let rootViewController = rootViewController as? UINavigationViewController  else { return }
        
        mainVC.delegate = self
        rootViewController.push(mainVC, animated: true)
    }

As you can see, although I've created the coordinator to accept any subclass of UIViewController it has been coupled in the start function to the concrete implementation of UIViewController: MainViewController.如您所见,虽然我创建了协调器来接受 UIViewController 的任何子类,但它在开始时已将 function 耦合到 UIViewController 的具体实现:MainViewController。

So my question is how to decouple it from MainViewController and have it more polymorphic ?所以我的问题是如何将它与 MainViewController 分离并使其更具多态性

You can pass coordinator as a parameter type in factory function and set delegate directly in factory function while creating controller instance.您可以在工厂 function 中将协调器作为参数类型传递,并在创建 controller 实例时直接在工厂 function 中设置delegate That way you wouldn't have to expose controller type explicitly out of factory classes.这样您就不必从工厂类中显式公开 controller type

I came up with below approach.我想出了以下方法。

protocol Coordinator {
    var rootViewController: UIViewController { get set }
    func start()
}

protocol UIViewControllerFactory {
    func getViewController(delegateType:CoordinatoreTypes,delegateObject:Coordinator) -> UIViewController?
}

class MainCoordinator: Coordinator {
    var rootViewController: UIViewController
    let factory: UIViewControllerFactory
    
    init(rootViewController: UIViewController, factory: UIViewControllerFactory) {
        self.rootViewController = rootViewController
        self.factory = factory
    }
    
    func start() {
        guard let controller = factory.getViewController(delegateType: .MainCoordinator, delegateObject: self),let rootViewController = rootViewController as? UINavigationViewController else {
            return
        }
        rootViewController.push(mainVC, animated: true)
    }
}

extension MainCoordinator:DelegateCaller{
    func printHello() {
        print("helloo")
    }
}

enum CoordinatoreTypes{
    case MainCoordinator
    case none
}

class Factory:UIViewControllerFactory{
    func getViewController(delegateType:CoordinatoreTypes,delegateObject:Coordinator) -> UIViewController?{
        switch delegateType{
        case .MainCoordinator:
            let controller = MainViewController()
            controller.delegate = delegateObject as? MainCoordinator
            return controller
        case .none:
            break
        }
        return nil
    }
}

class MainViewController:UIViewController{
    weak var delegate:DelegateCaller?
}

protocol DelegateCaller:AnyObject{
    func printHello()
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM