简体   繁体   English

清洁 Swift / VIPER 协议一致性

[英]Clean Swift / VIPER protocol conformance

I am currently working on a Clean Swift (similar to VIPER) implementation.我目前正在研究 Clean Swift(类似于 VIPER)实现。 For each module I have a Presenter and a Displayer (which is a ViewControler in the end) all of it based on protocols.对于每个模块,我都有一个 Presenter 和一个 Displayer(最终是一个 ViewControler),所有这些都基于协议。

Those are my generic Displayer and Presenter protocols:这些是我的通用 Displayer 和 Presenter 协议:

// Generic Displayer
protocol BaseDisplayLogic: class {
    func displayError(message: String)
    func displayApiError(error: ApiError)
}

extension BaseDisplayLogic where Self: UIViewController {
    func displayApiError(error: ApiError) {
        if let errorDescription = error.errorDescription {
            self.warningAlert(errorDescription)
        }
    }

    func displayError(message: String) {

    }
}

// Generic Presenter
protocol BasePresentationLogic: class  {

    var viewController: BaseDisplayLogic? { get }


    func presentError(message: String)
    func presentApiError(error: ApiError)

}

extension BasePresentationLogic {


    func presentError(message: String) {

    }

    func presentApiError(error: ApiError) {

    }
}

And here it is the implementation of a module I would need:这是我需要的模块的实现:

// A displayer
protocol RestorePasswordDisplayLogic: BaseDisplayLogic {
    func displayPasswordRestore(ok: Bool)
}

class RestorePasswordViewController: UIViewController {
}


// A presenter
protocol RestorePasswordPresentationLogic: BasePresentationLogic {
    func presentPasswordRestore(ok: Bool)
}

class RestorePasswordPresenter: RestorePasswordPresentationLogic {
    weak var viewController: RestorePasswordDisplayLogic?


    func presentPasswordRestore(ok: Bool) {
        self.viewController?.displayPasswordRestore(ok: ok)
    }

}

The problem is that I am getting an error in the Presenter implementation (RestorePasswordPresenter in this case) because it is not conforming to the BasePresentationLogic protocol.问题是我在 Presenter 实现中遇到错误(在这种情况下为 RestorePasswordPresenter),因为它不符合 BasePresentationLogic 协议。 If I remove the如果我删除

var viewController: BaseDisplayLogic? { get }

it works perfectly, but I need the viewController var to be visible from the BasePresentationLogic extension so I can make a default implementation of the presentError and presentApiError methods.它工作得很好,但我需要从 BasePresentationLogic 扩展中看到 viewController var,以便我可以对 presentError 和 presentApiError 方法进行默认实现。

Any idea on that?对此有任何想法吗?

The direct problem is that you're not conforming to the protocol as required.直接的问题是您没有按照要求遵守协议。 You required a viewController of type BaseDisplayLogic?您需要viewController类型的BaseDisplayLogic? . . So you need to create that, and store your more specific version in a backing variable:所以你需要创建它,并将你更具体的版本存储在一个支持变量中:

weak var restorePasswordViewController: RestorePasswordDisplayLogic?
var viewController: BaseDisplayLogic? { restorePasswordViewController }

(Personally, and only as an opinion, I think this is wildly overusing protocols, and likely to be a source of many headaches, especially if you ever try to make these pieces generic and start needing type-erasers. If you've been successful with it, more power to you, but maintaining all these parallel class/protocol hierarchies seems a bad idea to me. It's reinventing class inheritance with protocols, which isn't what protocols are for, and they're not very good at it.) (就个人而言,并且仅作为一种观点,我认为这是过度使用协议,并且可能是许多令人头疼的问题,特别是如果您尝试使这些部分通用并开始需要类型橡皮擦。如果您成功了有了它,你就有了更多的权力,但维护所有这些并行的类/协议层次结构对我来说似乎是个坏主意。它正在用协议重新发明 class inheritance,这不是协议的用途,而且它们也不是很擅长。 )

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

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