I am trying to create a ViewModel from a factory , the listener is the ViewController where we want the view model instance.
The controller is the listener for state changes. There are two problems with this design
- I can easily create with FolderFileListViewModelHandler in MyController, but have to type cast to Self. Not sure why. Ideally I should just pass Self.
- ViewModelHandlerFactory should return FolderFileListViewModelHandler as FolderFileListViewModel.
But I get the following error.
Protocol 'FolderFileListViewModel' can only be used as a generic constraint because it has Self or associated type requirements
I am using generic here because like FolderFileListViewModel
I want to constraint for a specific event type ex: FolderFileListModelStates
. I can create another ViewModel from StateListViewModel and constraint to another type of StateEvents.
protocol StateEvents {}
enum FolderFileListModelStates: StateEvents {
case initiated, loading , listAvailable
}
protocol StateListViewModel{
associatedtype Listener: StateListListener
}
protocol StateListListener:AnyObject {
associatedtype Events: StateEvents
func moved(to state: Events)
}
protocol FolderFileListViewModel:StateListViewModel where Self.Listener.Events == FolderFileListModelStates {
func getFileList(for folderName:String, subFolderName:String)
func setListener(listener: Listener)
}
class FolderFileListViewModelHandler<T:StateListListener>: FolderFileListViewModel where T.Events == FolderFileListModelStates{
func getFileList(for folderName: String, subFolderName: String) {
// Will call listener.moved(to: FolderFileListModelStates.listAvailable)
}
func setListener(listener: T) {
self.listener = listener
}
weak var listener: T?
typealias Listener = T
}
class ViewModelHandlerFactory {
private init() {}
static let shared = ViewModelHandlerFactory()
/// Method should only return FolderFileListViewModel.
/// Compile Error
func getVM() -> FolderFileListViewModel {
return FolderFileListViewModelHandler<MyController>()
}
}
class MyController: UIViewController {
func createViewModel() {
let handler = FolderFileListViewModelHandler<Self>()
// How can I improve this
handler.setListener(listener: self as! Self)
}
}
extension MyController: StateListListener {
func moved(to state: FolderFileListModelStates) {
}
}