티스토리 뷰

안녕하세요 Hani입니다.

BaseViewController를 어떻게 만들까 고민한 결과를 적어볼까 해요. ☺️

 

 

class ViewController<T: BaseViewModel>: UIViewController {
    
    let viewModel: T
    private var cancellables = Set<AnyCancellable>()

    init(viewModel: T) {
        self.viewModel = viewModel
        super.init(nibName: nil, bundle: nil)
    }
    
    init?(coder: NSCoder, viewModel: T) {
        self.viewModel = viewModel
        super.init(coder: coder)
    }
    
    @available(*, unavailable)
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func bindViewModel()
    
}

BaseViewModel 프로토콜을 Generic Constraint로 지정해서

꼭 외부에서 BaseViewModel를 준수하는 뷰모델을 주입해야 하도록 만들었습니다.

 

하지만 ViewController를 상속받는 뷰컨트롤러에서 bindViewModel을 강제로 Override하도록 만들 수 없습니다.

 

 

typealias BaseViewController<T> = ViewController<T> & BindViewModelProtocol where T: BaseViewModel

protocol BindViewModelProtocol {
    
    func bindViewModel()
    
}

class ViewController<T: BaseViewModel>: UIViewController {
    
    let viewModel: T
    private var cancellables = Set<AnyCancellable>()

    init(viewModel: T) {
        self.viewModel = viewModel
        super.init(nibName: nil, bundle: nil)
    }
    
    init?(coder: NSCoder, viewModel: T) {
        self.viewModel = viewModel
        super.init(coder: coder)
    }
    
    @available(*, unavailable)
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
}

bindViewModel을 서브클래스에서 반드시 구현하도록 만들기 위해서 Typealias를 사용했습니다.

 

Typealias로 ViewController를 상속, BindViewModelProtocol을 채택하도록 만들어야 하는데

ViewController이 Generic으로 구성되어 있기 때문에

Generic Typealias로 구현해봤어용.

 

 


References

https://github.com/apple/swift-evolution/blob/main/proposals/0048-generic-typealias.md

댓글