Reputation: 911
The idea is to implement MVP structure with base protocols and classes which hold reference to generic view and presenter
// --- Base --- //
protocol BaseViewProtocol: class {
associatedtype P: BasePresenterProtocol
var presenter: P? { get set }
}
class BaseView<P: BasePresenterProtocol>: UIView, BaseViewProtocol {
var presenter: P?
}
protocol BasePresenterProtocol {
associatedtype V: BaseViewProtocol
weak var view: V? { get set }
}
class BasePresenter<V: BaseViewProtocol>: BasePresenterProtocol {
weak var view: V?
}
// --- Current --- //
protocol CurrentViewProtocol: BaseViewProtocol {
}
class CurrentView<P: CurrentPresenterProtocol>: BaseView<P>, CurrentViewProtocol {
}
protocol CurrentPresenterProtocol: BasePresenterProtocol {
}
class CurrentPresenter<V: CurrentViewProtocol>: BasePresenter<V>, CurrentPresenterProtocol {
init(currentView: V) {
super.init()
self.view = currentView
}
}
The question is how to instantiate concrete implementation of all these classes, since both View and Presenter are generic classes and depend on each other
Upvotes: 0
Views: 693
Reputation: 1183
Not sure this is best way but i had done similar thing in this way
protocol Presentable {
associatedtype View: ViewAble
weak var view: View? {get set}
init(with view: View)
func onAttach(view: View)
func onDetach()
var isAttached: Bool {get}
}
extension Presentable {
var isAttached: Bool {
return view != nil
}
}
class Presenter: Presentable {
weak var view: ViewAble? {
didSet {
if let view = view {
onAttach(view: view)
} else {
onDetach()
}
}
}
required init(with view: ViewAble) {
self.view = view
}
func onAttach(view: View) {
//pre set up on construction
}
func onDetach() {
//release some resource on destroying view
}
}
@objc protocol ViewAble: class {
@objc optional func showError(_ message: String, _ callBack: (() -> Void)?)
}
extension ViewAble where Self: UIViewController {
func showAlert(_ message: String?, _ callBack: (() -> Void)? = nil) {
let alertController = UIAlertController(title: nil, message: message, preferredStyle: .alert)
alertController.addAction(UIAlertAction(title: "OK", style: .default) { action in
callBack?()
})
self.present(alertController, animated: true, completion: callBack)
}
func showLoading() {
//show default Loading here and override if want custom
}
func stopLoading() {
//stop default Loading
}
}
class ViewController: ViewAble {
}
Upvotes: 1