Trying to create a ViewModel with Listener using generics

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

  1. I can easily create with FolderFileListViewModelHandler in MyController, but have to type cast to Self. Not sure why. Ideally I should just pass Self.
  2. 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) {
        
    }
}
Terms of Service

Privacy Policy

Cookie Policy